summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x.ci/scripts/linux/docker.sh14
-rwxr-xr-x.ci/scripts/transifex/docker.sh12
-rwxr-xr-x.ci/scripts/windows/docker.sh6
-rw-r--r--.github/workflows/ci.yml4
-rw-r--r--CMakeLists.txt10
-rw-r--r--CMakeModules/GenerateSCMRev.cmake10
-rw-r--r--dist/icons/controller/applet_pro_controller_dark_disabled.pngbin4477 -> 2712 bytes
-rw-r--r--dist/icons/controller/applet_pro_controller_disabled.pngbin4173 -> 2630 bytes
-rw-r--r--dist/icons/controller/applet_pro_controller_midnight_disabled.pngbin4459 -> 2774 bytes
-rw-r--r--dist/icons/overlay/button_A.pngbin3494 -> 1647 bytes
-rw-r--r--dist/icons/overlay/button_B.pngbin3375 -> 1534 bytes
-rw-r--r--dist/icons/overlay/button_X.pngbin3968 -> 1748 bytes
-rw-r--r--dist/icons/overlay/button_Y.pngbin3337 -> 1504 bytes
-rw-r--r--dist/icons/overlay/button_press_stick.pngbin5225 -> 2477 bytes
-rw-r--r--dist/icons/overlay/controller_dual_joycon.pngbin7312 -> 3475 bytes
-rw-r--r--dist/icons/overlay/controller_dual_joycon_dark.pngbin5889 -> 3107 bytes
-rw-r--r--dist/icons/overlay/controller_handheld.pngbin4645 -> 2250 bytes
-rw-r--r--dist/icons/overlay/controller_handheld_dark.pngbin3745 -> 2000 bytes
-rw-r--r--dist/icons/overlay/controller_pro.pngbin9493 -> 4531 bytes
-rw-r--r--dist/icons/overlay/controller_pro_dark.pngbin7488 -> 4531 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_left.pngbin7489 -> 3605 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_left_dark.pngbin6768 -> 3447 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_left_y_dark.pngbin2639 -> 1035 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_right.pngbin7497 -> 3603 bytes
-rw-r--r--dist/icons/overlay/controller_single_joycon_right_dark.pngbin6729 -> 3406 bytes
-rw-r--r--dist/icons/overlay/osk_button_backspace.pngbin2919 -> 1272 bytes
-rw-r--r--dist/icons/overlay/osk_button_backspace_dark.pngbin2958 -> 1262 bytes
-rw-r--r--dist/languages/.tx/config2
-rw-r--r--dist/languages/README.md4
-rw-r--r--dist/languages/ca.ts962
-rw-r--r--dist/languages/cs.ts960
-rw-r--r--dist/languages/da.ts966
-rw-r--r--dist/languages/de.ts1084
-rw-r--r--dist/languages/el.ts1009
-rw-r--r--dist/languages/es.ts1015
-rw-r--r--dist/languages/fr.ts1190
-rw-r--r--dist/languages/id.ts962
-rw-r--r--dist/languages/it.ts1022
-rw-r--r--dist/languages/ja_JP.ts1012
-rw-r--r--dist/languages/ko_KR.ts1213
-rw-r--r--dist/languages/nb.ts960
-rw-r--r--dist/languages/nl.ts960
-rw-r--r--dist/languages/pl.ts962
-rw-r--r--dist/languages/pt_BR.ts1036
-rw-r--r--dist/languages/pt_PT.ts1036
-rw-r--r--dist/languages/ru_RU.ts972
-rw-r--r--dist/languages/sv.ts956
-rw-r--r--dist/languages/tr_TR.ts1186
-rw-r--r--dist/languages/uk.ts7321
-rw-r--r--dist/languages/vi.ts956
-rw-r--r--dist/languages/vi_VN.ts956
-rw-r--r--dist/languages/zh_CN.ts982
-rw-r--r--dist/languages/zh_TW.ts968
-rw-r--r--dist/qt_themes/colorful/icons/48x48/bad_folder.pngbin15494 -> 528 bytes
-rw-r--r--dist/qt_themes/default/icons/256x256/plus_folder.pngbin3521 -> 1948 bytes
-rw-r--r--dist/qt_themes/default/icons/256x256/yuzu.pngbin6751 -> 4425 bytes
-rw-r--r--dist/qt_themes/qdarkstyle/icons/256x256/plus_folder.pngbin3931 -> 1924 bytes
-rw-r--r--externals/ffmpeg/CMakeLists.txt2
-rw-r--r--externals/libusb/CMakeLists.txt2
-rw-r--r--src/CMakeLists.txt34
-rw-r--r--src/audio_core/CMakeLists.txt11
-rw-r--r--src/audio_core/audio_core.cpp2
-rw-r--r--src/audio_core/audio_manager.cpp17
-rw-r--r--src/audio_core/audio_manager.h19
-rw-r--r--src/audio_core/in/audio_in_system.cpp8
-rw-r--r--src/audio_core/in/audio_in_system.h2
-rw-r--r--src/audio_core/out/audio_out_system.cpp10
-rw-r--r--src/audio_core/out/audio_out_system.h4
-rw-r--r--src/audio_core/renderer/adsp/audio_renderer.cpp4
-rw-r--r--src/audio_core/renderer/adsp/audio_renderer.h2
-rw-r--r--src/audio_core/renderer/behavior/info_updater.cpp2
-rw-r--r--src/audio_core/renderer/command/effect/biquad_filter.cpp2
-rw-r--r--src/audio_core/renderer/command/effect/multi_tap_biquad_filter.cpp2
-rw-r--r--src/audio_core/renderer/system.cpp89
-rw-r--r--src/audio_core/renderer/system.h16
-rw-r--r--src/audio_core/renderer/system_manager.cpp2
-rw-r--r--src/audio_core/renderer/voice/voice_context.cpp4
-rw-r--r--src/audio_core/sink/cubeb_sink.cpp31
-rw-r--r--src/audio_core/sink/cubeb_sink.h7
-rw-r--r--src/audio_core/sink/sdl2_sink.cpp14
-rw-r--r--src/audio_core/sink/sdl2_sink.h7
-rw-r--r--src/audio_core/sink/sink_details.cpp66
-rw-r--r--src/audio_core/sink/sink_details.h2
-rw-r--r--src/audio_core/sink/sink_stream.cpp9
-rw-r--r--src/common/CMakeLists.txt46
-rw-r--r--src/common/address_space.cpp10
-rw-r--r--src/common/address_space.h150
-rw-r--r--src/common/address_space.inc366
-rw-r--r--src/common/algorithm.h8
-rw-r--r--src/common/bit_field.h15
-rw-r--r--src/common/bounded_threadsafe_queue.h9
-rw-r--r--src/common/concepts.h24
-rw-r--r--src/common/fixed_point.h274
-rw-r--r--src/common/fs/file.h12
-rw-r--r--src/common/hash.h7
-rw-r--r--src/common/input.h35
-rw-r--r--src/common/logging/backend.cpp2
-rw-r--r--src/common/multi_level_page_table.cpp9
-rw-r--r--src/common/multi_level_page_table.h78
-rw-r--r--src/common/multi_level_page_table.inc84
-rw-r--r--src/common/settings.h3
-rw-r--r--src/core/CMakeLists.txt34
-rw-r--r--src/core/arm/arm_interface.cpp8
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp3
-rw-r--r--src/core/core.cpp115
-rw-r--r--src/core/core.h29
-rw-r--r--src/core/core_timing.cpp40
-rw-r--r--src/core/core_timing.h14
-rw-r--r--src/core/cpu_manager.cpp4
-rw-r--r--src/core/debugger/debugger.cpp2
-rw-r--r--src/core/device_memory.h10
-rw-r--r--src/core/file_sys/card_image.cpp4
-rw-r--r--src/core/file_sys/control_metadata.cpp43
-rw-r--r--src/core/file_sys/control_metadata.h6
-rw-r--r--src/core/file_sys/program_metadata.cpp54
-rw-r--r--src/core/file_sys/program_metadata.h14
-rw-r--r--src/core/file_sys/savedata_factory.cpp58
-rw-r--r--src/core/file_sys/savedata_factory.h4
-rw-r--r--src/core/frontend/framebuffer_layout.cpp2
-rw-r--r--src/core/frontend/framebuffer_layout.h1
-rw-r--r--src/core/hardware_interrupt_manager.cpp32
-rw-r--r--src/core/hardware_interrupt_manager.h32
-rw-r--r--src/core/hid/emulated_controller.cpp144
-rw-r--r--src/core/hid/emulated_controller.h39
-rw-r--r--src/core/hid/input_converter.cpp22
-rw-r--r--src/core/hid/input_converter.h8
-rw-r--r--src/core/hid/irs_types.h20
-rw-r--r--src/core/hle/ipc_helpers.h17
-rw-r--r--src/core/hle/kernel/global_scheduler_context.cpp22
-rw-r--r--src/core/hle/kernel/global_scheduler_context.h8
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp105
-rw-r--r--src/core/hle/kernel/hle_ipc.h40
-rw-r--r--src/core/hle/kernel/init/init_slab_setup.cpp8
-rw-r--r--src/core/hle/kernel/k_class_token.cpp12
-rw-r--r--src/core/hle/kernel/k_class_token.h1
-rw-r--r--src/core/hle/kernel/k_client_port.cpp5
-rw-r--r--src/core/hle/kernel/k_client_port.h3
-rw-r--r--src/core/hle/kernel/k_client_session.cpp18
-rw-r--r--src/core/hle/kernel/k_client_session.h3
-rw-r--r--src/core/hle/kernel/k_code_memory.cpp2
-rw-r--r--src/core/hle/kernel/k_dynamic_page_manager.h136
-rw-r--r--src/core/hle/kernel/k_dynamic_resource_manager.h58
-rw-r--r--src/core/hle/kernel/k_dynamic_slab_heap.h122
-rw-r--r--src/core/hle/kernel/k_event.cpp44
-rw-r--r--src/core/hle/kernel/k_event.h31
-rw-r--r--src/core/hle/kernel/k_interrupt_manager.cpp29
-rw-r--r--src/core/hle/kernel/k_interrupt_manager.h4
-rw-r--r--src/core/hle/kernel/k_linked_list.h1
-rw-r--r--src/core/hle/kernel/k_memory_block.h506
-rw-r--r--src/core/hle/kernel/k_memory_block_manager.cpp409
-rw-r--r--src/core/hle/kernel/k_memory_block_manager.h145
-rw-r--r--src/core/hle/kernel/k_memory_manager.cpp2
-rw-r--r--src/core/hle/kernel/k_page_buffer.cpp2
-rw-r--r--src/core/hle/kernel/k_page_buffer.h1
-rw-r--r--src/core/hle/kernel/k_page_table.cpp1302
-rw-r--r--src/core/hle/kernel/k_page_table.h319
-rw-r--r--src/core/hle/kernel/k_port.cpp6
-rw-r--r--src/core/hle/kernel/k_process.cpp112
-rw-r--r--src/core/hle/kernel/k_process.h83
-rw-r--r--src/core/hle/kernel/k_readable_event.cpp33
-rw-r--r--src/core/hle/kernel/k_readable_event.h17
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp26
-rw-r--r--src/core/hle/kernel/k_server_port.cpp6
-rw-r--r--src/core/hle/kernel/k_server_port.h19
-rw-r--r--src/core/hle/kernel/k_server_session.cpp434
-rw-r--r--src/core/hle/kernel/k_server_session.h89
-rw-r--r--src/core/hle/kernel/k_session.cpp5
-rw-r--r--src/core/hle/kernel/k_session.h3
-rw-r--r--src/core/hle/kernel/k_session_request.cpp61
-rw-r--r--src/core/hle/kernel/k_session_request.h306
-rw-r--r--src/core/hle/kernel/k_shared_memory.cpp2
-rw-r--r--src/core/hle/kernel/k_shared_memory.h4
-rw-r--r--src/core/hle/kernel/k_shared_memory_info.h3
-rw-r--r--src/core/hle/kernel/k_slab_heap.h27
-rw-r--r--src/core/hle/kernel/k_thread.cpp155
-rw-r--r--src/core/hle/kernel/k_thread.h12
-rw-r--r--src/core/hle/kernel/k_thread_local_page.h2
-rw-r--r--src/core/hle/kernel/k_worker_task_manager.cpp2
-rw-r--r--src/core/hle/kernel/k_writable_event.cpp35
-rw-r--r--src/core/hle/kernel/k_writable_event.h39
-rw-r--r--src/core/hle/kernel/kernel.cpp132
-rw-r--r--src/core/hle/kernel/kernel.h33
-rw-r--r--src/core/hle/kernel/service_thread.cpp230
-rw-r--r--src/core/hle/kernel/service_thread.h6
-rw-r--r--src/core/hle/kernel/slab_helpers.h2
-rw-r--r--src/core/hle/kernel/svc.cpp206
-rw-r--r--src/core/hle/kernel/svc_common.h7
-rw-r--r--src/core/hle/kernel/svc_types.h13
-rw-r--r--src/core/hle/kernel/svc_wrap.h32
-rw-r--r--src/core/hle/result.h130
-rw-r--r--src/core/hle/service/acc/acc.cpp34
-rw-r--r--src/core/hle/service/acc/acc.h1
-rw-r--r--src/core/hle/service/acc/acc_u0.cpp2
-rw-r--r--src/core/hle/service/acc/async_context.cpp2
-rw-r--r--src/core/hle/service/acc/profile_manager.cpp25
-rw-r--r--src/core/hle/service/acc/profile_manager.h3
-rw-r--r--src/core/hle/service/am/am.cpp25
-rw-r--r--src/core/hle/service/am/am.h1
-rw-r--r--src/core/hle/service/am/applets/applets.cpp10
-rw-r--r--src/core/hle/service/am/applets/applets.h2
-rw-r--r--src/core/hle/service/audio/audctl.cpp16
-rw-r--r--src/core/hle/service/audio/audin_u.cpp2
-rw-r--r--src/core/hle/service/audio/audout_u.cpp2
-rw-r--r--src/core/hle/service/audio/audren_u.cpp30
-rw-r--r--src/core/hle/service/bcat/backend/backend.cpp2
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp14
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.h1
-rw-r--r--src/core/hle/service/friend/friend.cpp13
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp40
-rw-r--r--src/core/hle/service/hid/controllers/palma.cpp229
-rw-r--r--src/core/hle/service/hid/controllers/palma.h163
-rw-r--r--src/core/hle/service/hid/errors.h2
-rw-r--r--src/core/hle/service/hid/hid.cpp447
-rw-r--r--src/core/hle/service/hid/hid.h29
-rw-r--r--src/core/hle/service/hid/hidbus/ringcon.cpp8
-rw-r--r--src/core/hle/service/hid/irs.cpp3
-rw-r--r--src/core/hle/service/hid/irsensor/pointing_processor.h4
-rw-r--r--src/core/hle/service/kernel_helpers.cpp5
-rw-r--r--src/core/hle/service/ldn/lan_discovery.cpp633
-rw-r--r--src/core/hle/service/ldn/lan_discovery.h134
-rw-r--r--src/core/hle/service/ldn/ldn.cpp229
-rw-r--r--src/core/hle/service/ldn/ldn_types.h48
-rw-r--r--src/core/hle/service/ldr/ldr.cpp4
-rw-r--r--src/core/hle/service/mii/mii_manager.cpp161
-rw-r--r--src/core/hle/service/mii/mii_manager.h4
-rw-r--r--src/core/hle/service/nfc/nfc.cpp8
-rw-r--r--src/core/hle/service/nfp/amiibo_crypto.cpp87
-rw-r--r--src/core/hle/service/nfp/amiibo_crypto.h13
-rw-r--r--src/core/hle/service/nfp/nfp.cpp1093
-rw-r--r--src/core/hle/service/nfp/nfp.h161
-rw-r--r--src/core/hle/service/nfp/nfp_device.cpp690
-rw-r--r--src/core/hle/service/nfp/nfp_device.h100
-rw-r--r--src/core/hle/service/nfp/nfp_result.h24
-rw-r--r--src/core/hle/service/nfp/nfp_types.h (renamed from src/core/hle/service/nfp/amiibo_types.h)154
-rw-r--r--src/core/hle/service/nfp/nfp_user.cpp661
-rw-r--r--src/core/hle/service/nfp/nfp_user.h50
-rw-r--r--src/core/hle/service/nim/nim.cpp4
-rw-r--r--src/core/hle/service/ns/ns.cpp30
-rw-r--r--src/core/hle/service/ns/ns.h3
-rw-r--r--src/core/hle/service/nvdrv/core/container.cpp50
-rw-r--r--src/core/hle/service/nvdrv/core/container.h52
-rw-r--r--src/core/hle/service/nvdrv/core/nvmap.cpp273
-rw-r--r--src/core/hle/service/nvdrv/core/nvmap.h176
-rw-r--r--src/core/hle/service/nvdrv/core/syncpoint_manager.cpp121
-rw-r--r--src/core/hle/service/nvdrv/core/syncpoint_manager.h134
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdevice.h8
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp19
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.h15
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp496
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h191
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp364
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.h114
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp25
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h14
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp129
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.h54
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp16
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h6
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp81
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h23
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp20
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.h6
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.cpp233
-rw-r--r--src/core/hle/service/nvdrv/devices/nvmap.h56
-rw-r--r--src/core/hle/service/nvdrv/nvdata.h17
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp131
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h123
-rw-r--r--src/core/hle/service/nvdrv/nvdrv_interface.cpp31
-rw-r--r--src/core/hle/service/nvdrv/nvdrv_interface.h6
-rw-r--r--src/core/hle/service/nvdrv/syncpoint_manager.cpp38
-rw-r--r--src/core/hle/service/nvdrv/syncpoint_manager.h84
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_consumer.cpp9
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_consumer.h8
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_producer.cpp26
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_producer.h10
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp55
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h15
-rw-r--r--src/core/hle/service/ptm/psm.cpp6
-rw-r--r--src/core/hle/service/ptm/ts.cpp15
-rw-r--r--src/core/hle/service/ptm/ts.h1
-rw-r--r--src/core/hle/service/service.cpp25
-rw-r--r--src/core/hle/service/service.h6
-rw-r--r--src/core/hle/service/set/set_sys.cpp79
-rw-r--r--src/core/hle/service/set/set_sys.h2
-rw-r--r--src/core/hle/service/sm/sm.cpp43
-rw-r--r--src/core/hle/service/sm/sm.h2
-rw-r--r--src/core/hle/service/sm/sm_controller.cpp40
-rw-r--r--src/core/hle/service/sockets/bsd.cpp2
-rw-r--r--src/core/hle/service/time/system_clock_context_update_callback.cpp10
-rw-r--r--src/core/hle/service/time/system_clock_context_update_callback.h6
-rw-r--r--src/core/hle/service/vi/display/vi_display.cpp34
-rw-r--r--src/core/hle/service/vi/display/vi_display.h27
-rw-r--r--src/core/hle/service/vi/vi.cpp49
-rw-r--r--src/core/hle/service/vi/vi_results.h15
-rw-r--r--src/core/internal_network/network.cpp12
-rw-r--r--src/core/internal_network/network_interface.cpp12
-rw-r--r--src/core/internal_network/network_interface.h1
-rw-r--r--src/core/internal_network/socket_proxy.cpp8
-rw-r--r--src/core/internal_network/sockets.h11
-rw-r--r--src/core/loader/loader.cpp4
-rw-r--r--src/core/memory.cpp52
-rw-r--r--src/core/memory.h1
-rw-r--r--src/dedicated_room/CMakeLists.txt2
-rw-r--r--src/dedicated_room/yuzu_room.cpp13
-rw-r--r--src/input_common/CMakeLists.txt11
-rw-r--r--src/input_common/drivers/gc_adapter.cpp10
-rw-r--r--src/input_common/drivers/gc_adapter.h4
-rw-r--r--src/input_common/drivers/mouse.cpp2
-rw-r--r--src/input_common/drivers/sdl_driver.cpp72
-rw-r--r--src/input_common/drivers/sdl_driver.h4
-rw-r--r--src/input_common/drivers/virtual_amiibo.cpp101
-rw-r--r--src/input_common/drivers/virtual_amiibo.h61
-rw-r--r--src/input_common/input_engine.cpp37
-rw-r--r--src/input_common/input_engine.h24
-rw-r--r--src/input_common/input_poller.cpp96
-rw-r--r--src/input_common/input_poller.h10
-rw-r--r--src/input_common/main.cpp21
-rw-r--r--src/input_common/main.h7
-rw-r--r--src/network/network.cpp2
-rw-r--r--src/network/room.cpp63
-rw-r--r--src/network/room.h1
-rw-r--r--src/network/room_member.cpp57
-rw-r--r--src/network/room_member.h35
-rw-r--r--src/shader_recompiler/CMakeLists.txt14
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm.cpp2
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp25
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp4
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl.cpp2
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp4
-rw-r--r--src/shader_recompiler/frontend/ir/microinstruction.cpp5
-rw-r--r--src/shader_recompiler/frontend/ir/value.h4
-rw-r--r--src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp6
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate_program.cpp47
-rw-r--r--src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp98
-rw-r--r--src/shader_recompiler/ir_opt/texture_pass.cpp98
-rw-r--r--src/shader_recompiler/runtime_info.h2
-rw-r--r--src/shader_recompiler/shader_info.h7
-rw-r--r--src/tests/core/core_timing.cpp3
-rw-r--r--src/tests/video_core/buffer_base.cpp2
-rw-r--r--src/video_core/CMakeLists.txt60
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h176
-rw-r--r--src/video_core/cdma_pusher.cpp29
-rw-r--r--src/video_core/cdma_pusher.h18
-rw-r--r--src/video_core/command_classes/host1x.cpp29
-rw-r--r--src/video_core/control/channel_state.cpp40
-rw-r--r--src/video_core/control/channel_state.h68
-rw-r--r--src/video_core/control/channel_state_cache.cpp14
-rw-r--r--src/video_core/control/channel_state_cache.h101
-rw-r--r--src/video_core/control/channel_state_cache.inc86
-rw-r--r--src/video_core/control/scheduler.cpp32
-rw-r--r--src/video_core/control/scheduler.h37
-rw-r--r--src/video_core/dirty_flags.cpp24
-rw-r--r--src/video_core/dma_pusher.cpp26
-rw-r--r--src/video_core/dma_pusher.h39
-rw-r--r--src/video_core/engines/engine_upload.cpp46
-rw-r--r--src/video_core/engines/engine_upload.h6
-rw-r--r--src/video_core/engines/kepler_compute.cpp13
-rw-r--r--src/video_core/engines/kepler_memory.cpp13
-rw-r--r--src/video_core/engines/maxwell_3d.cpp578
-rw-r--r--src/video_core/engines/maxwell_3d.h3877
-rw-r--r--src/video_core/engines/maxwell_dma.cpp236
-rw-r--r--src/video_core/engines/maxwell_dma.h8
-rw-r--r--src/video_core/engines/puller.cpp305
-rw-r--r--src/video_core/engines/puller.h177
-rw-r--r--src/video_core/fence_manager.h104
-rw-r--r--src/video_core/gpu.cpp706
-rw-r--r--src/video_core/gpu.h143
-rw-r--r--src/video_core/gpu_thread.cpp24
-rw-r--r--src/video_core/gpu_thread.h14
-rw-r--r--src/video_core/host1x/codecs/codec.cpp (renamed from src/video_core/command_classes/codecs/codec.cpp)44
-rw-r--r--src/video_core/host1x/codecs/codec.h (renamed from src/video_core/command_classes/codecs/codec.h)21
-rw-r--r--src/video_core/host1x/codecs/h264.cpp (renamed from src/video_core/command_classes/codecs/h264.cpp)17
-rw-r--r--src/video_core/host1x/codecs/h264.h (renamed from src/video_core/command_classes/codecs/h264.h)16
-rw-r--r--src/video_core/host1x/codecs/vp8.cpp (renamed from src/video_core/command_classes/codecs/vp8.cpp)12
-rw-r--r--src/video_core/host1x/codecs/vp8.h (renamed from src/video_core/command_classes/codecs/vp8.h)15
-rw-r--r--src/video_core/host1x/codecs/vp9.cpp (renamed from src/video_core/command_classes/codecs/vp9.cpp)23
-rw-r--r--src/video_core/host1x/codecs/vp9.h (renamed from src/video_core/command_classes/codecs/vp9.h)22
-rw-r--r--src/video_core/host1x/codecs/vp9_types.h (renamed from src/video_core/command_classes/codecs/vp9_types.h)1
-rw-r--r--src/video_core/host1x/control.cpp33
-rw-r--r--src/video_core/host1x/control.h (renamed from src/video_core/command_classes/host1x.h)20
-rw-r--r--src/video_core/host1x/host1x.cpp17
-rw-r--r--src/video_core/host1x/host1x.h57
-rw-r--r--src/video_core/host1x/nvdec.cpp (renamed from src/video_core/command_classes/nvdec.cpp)11
-rw-r--r--src/video_core/host1x/nvdec.h (renamed from src/video_core/command_classes/nvdec.h)14
-rw-r--r--src/video_core/host1x/nvdec_common.h (renamed from src/video_core/command_classes/nvdec_common.h)4
-rw-r--r--src/video_core/host1x/sync_manager.cpp (renamed from src/video_core/command_classes/sync_manager.cpp)13
-rw-r--r--src/video_core/host1x/sync_manager.h (renamed from src/video_core/command_classes/sync_manager.h)12
-rw-r--r--src/video_core/host1x/syncpoint_manager.cpp106
-rw-r--r--src/video_core/host1x/syncpoint_manager.h98
-rw-r--r--src/video_core/host1x/vic.cpp (renamed from src/video_core/command_classes/vic.cpp)36
-rw-r--r--src/video_core/host1x/vic.h (renamed from src/video_core/command_classes/vic.h)13
-rw-r--r--src/video_core/host_shaders/astc_decoder.comp2
-rw-r--r--src/video_core/macro/macro.cpp1
-rw-r--r--src/video_core/macro/macro_hle.cpp118
-rw-r--r--src/video_core/macro/macro_interpreter.cpp2
-rw-r--r--src/video_core/macro/macro_jit_x64.cpp64
-rw-r--r--src/video_core/memory_manager.cpp785
-rw-r--r--src/video_core/memory_manager.h189
-rw-r--r--src/video_core/pte_kind.h264
-rw-r--r--src/video_core/query_cache.h22
-rw-r--r--src/video_core/rasterizer_interface.h22
-rw-r--r--src/video_core/renderer_base.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_compute_pipeline.cpp20
-rw-r--r--src/video_core/renderer_opengl/gl_compute_pipeline.h16
-rw-r--r--src/video_core/renderer_opengl/gl_fence_manager.cpp13
-rw-r--r--src/video_core/renderer_opengl/gl_fence_manager.h6
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp58
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.h20
-rw-r--r--src/video_core/renderer_opengl/gl_query_cache.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_query_cache.h3
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp353
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h26
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp86
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h9
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.cpp70
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.h83
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h291
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp2
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.cpp303
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h15
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.cpp341
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.h2
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp8
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp19
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.h7
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pass.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pipeline.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_fence_manager.cpp15
-rw-r--r--src/video_core/renderer_vulkan/vk_fence_manager.h6
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp32
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.h28
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp104
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.h6
-rw-r--r--src/video_core/renderer_vulkan/vk_query_cache.cpp14
-rw-r--r--src/video_core/renderer_vulkan/vk_query_cache.h5
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp266
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h34
-rw-r--r--src/video_core/renderer_vulkan/vk_scheduler.cpp8
-rw-r--r--src/video_core/renderer_vulkan/vk_scheduler.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.cpp68
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.h27
-rw-r--r--src/video_core/renderer_vulkan/vk_swapchain.cpp15
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp47
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h16
-rw-r--r--src/video_core/shader_cache.cpp37
-rw-r--r--src/video_core/shader_cache.h15
-rw-r--r--src/video_core/shader_environment.cpp23
-rw-r--r--src/video_core/shader_environment.h2
-rw-r--r--src/video_core/surface.cpp17
-rw-r--r--src/video_core/surface.h16
-rw-r--r--src/video_core/texture_cache/descriptor_table.h2
-rw-r--r--src/video_core/texture_cache/format_lookup_table.cpp8
-rw-r--r--src/video_core/texture_cache/formatter.h8
-rw-r--r--src/video_core/texture_cache/image_base.cpp13
-rw-r--r--src/video_core/texture_cache/image_base.h3
-rw-r--r--src/video_core/texture_cache/image_info.cpp37
-rw-r--r--src/video_core/texture_cache/render_targets.h1
-rw-r--r--src/video_core/texture_cache/texture_cache.cpp15
-rw-r--r--src/video_core/texture_cache/texture_cache.h229
-rw-r--r--src/video_core/texture_cache/texture_cache_base.h85
-rw-r--r--src/video_core/texture_cache/util.cpp3
-rw-r--r--src/video_core/textures/astc.cpp8
-rw-r--r--src/video_core/textures/decoders.cpp242
-rw-r--r--src/video_core/textures/decoders.h33
-rw-r--r--src/video_core/transform_feedback.cpp118
-rw-r--r--src/video_core/transform_feedback.h3
-rw-r--r--src/video_core/vulkan_common/vulkan_wrapper.h20
-rw-r--r--src/web_service/web_backend.cpp3
-rw-r--r--src/yuzu/applets/qt_controller.cpp2
-rw-r--r--src/yuzu/applets/qt_controller.ui2
-rw-r--r--src/yuzu/bootmanager.cpp6
-rw-r--r--src/yuzu/configuration/config.cpp4
-rw-r--r--src/yuzu/configuration/configure_audio.cpp4
-rw-r--r--src/yuzu/configuration/configure_debug.cpp2
-rw-r--r--src/yuzu/configuration/configure_debug.ui10
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp7
-rw-r--r--src/yuzu/configuration/configure_graphics.ui5
-rw-r--r--src/yuzu/configuration/configure_input.cpp7
-rw-r--r--src/yuzu/configuration/configure_ui.cpp3
-rw-r--r--src/yuzu/configuration/configure_ui.ui7
-rw-r--r--src/yuzu/configuration/input_profiles.cpp2
-rw-r--r--src/yuzu/game_list.cpp2
-rw-r--r--src/yuzu/main.cpp103
-rw-r--r--src/yuzu/main.h1
-rw-r--r--src/yuzu/main.ui25
-rw-r--r--src/yuzu/multiplayer/chat_room.cpp12
-rw-r--r--src/yuzu/multiplayer/client_room.cpp3
-rw-r--r--src/yuzu/multiplayer/direct_connect.cpp2
-rw-r--r--src/yuzu/multiplayer/direct_connect.h1
-rw-r--r--src/yuzu/multiplayer/host_room.cpp1
-rw-r--r--src/yuzu/multiplayer/host_room.h3
-rw-r--r--src/yuzu/multiplayer/lobby.cpp67
-rw-r--r--src/yuzu/multiplayer/lobby.h8
-rw-r--r--src/yuzu/multiplayer/lobby_p.h18
-rw-r--r--src/yuzu/multiplayer/message.cpp6
-rw-r--r--src/yuzu/multiplayer/state.cpp82
-rw-r--r--src/yuzu/multiplayer/state.h14
-rw-r--r--src/yuzu/startup_checks.cpp102
-rw-r--r--src/yuzu/startup_checks.h2
-rw-r--r--src/yuzu/uisettings.h5
-rw-r--r--src/yuzu_cmd/yuzu.cpp4
503 files changed, 40920 insertions, 20748 deletions
diff --git a/.ci/scripts/linux/docker.sh b/.ci/scripts/linux/docker.sh
index b9862d1c2..35c4a4368 100755
--- a/.ci/scripts/linux/docker.sh
+++ b/.ci/scripts/linux/docker.sh
@@ -33,16 +33,14 @@ DESTDIR="$PWD/AppDir" ninja install
rm -vf AppDir/usr/bin/yuzu-cmd AppDir/usr/bin/yuzu-tester
# Download tools needed to build an AppImage
-wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/linuxdeploy-x86_64.AppImage
-wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/linuxdeploy-plugin-qt-x86_64.AppImage
-wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/AppRun-patched-x86_64
+wget -nc https://raw.githubusercontent.com/yuzu-emu/ext-linux-bin/main/gcc/deploy-linux.sh
+wget -nc https://raw.githubusercontent.com/yuzu-emu/AppImageKit-checkrt/old/AppRun.sh
wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/exec-x86_64.so
# Set executable bit
chmod 755 \
- AppRun-patched-x86_64 \
+ deploy-linux.sh \
+ AppRun.sh \
exec-x86_64.so \
- linuxdeploy-x86_64.AppImage \
- linuxdeploy-plugin-qt-x86_64.AppImage
# Workaround for https://github.com/AppImage/AppImageKit/issues/828
export APPIMAGE_EXTRACT_AND_RUN=1
@@ -52,7 +50,7 @@ mkdir -p AppDir/usr/optional/libstdc++
mkdir -p AppDir/usr/optional/libgcc_s
# Deploy yuzu's needed dependencies
-./linuxdeploy-x86_64.AppImage --appdir AppDir --plugin qt
+DEPLOY_QT=1 ./deploy-linux.sh AppDir/usr/bin/yuzu AppDir
# Workaround for libQt5MultimediaGstTools indirectly requiring libwayland-client and breaking Vulkan usage on end-user systems
find AppDir -type f -regex '.*libwayland-client\.so.*' -delete -print
@@ -60,6 +58,6 @@ find AppDir -type f -regex '.*libwayland-client\.so.*' -delete -print
# Workaround for building yuzu with GCC 10 but also trying to distribute it to Ubuntu 18.04 et al.
# See https://github.com/darealshinji/AppImageKit-checkrt
cp exec-x86_64.so AppDir/usr/optional/exec.so
-cp AppRun-patched-x86_64 AppDir/AppRun
+cp AppRun.sh AppDir/AppRun
cp --dereference /usr/lib/x86_64-linux-gnu/libstdc++.so.6 AppDir/usr/optional/libstdc++/libstdc++.so.6
cp --dereference /lib/x86_64-linux-gnu/libgcc_s.so.1 AppDir/usr/optional/libgcc_s/libgcc_s.so.1
diff --git a/.ci/scripts/transifex/docker.sh b/.ci/scripts/transifex/docker.sh
index 6237b3f73..6ddbfd0dd 100755
--- a/.ci/scripts/transifex/docker.sh
+++ b/.ci/scripts/transifex/docker.sh
@@ -3,15 +3,6 @@
# SPDX-FileCopyrightText: 2021 yuzu Emulator Project
# SPDX-License-Identifier: GPL-2.0-or-later
-# Setup RC file for tx
-cat << EOF > ~/.transifexrc
-[https://www.transifex.com]
-hostname = https://www.transifex.com
-username = api
-password = $TRANSIFEX_API_TOKEN
-EOF
-
-
set -x
echo -e "\e[1m\e[33mBuild tools information:\e[0m"
@@ -19,9 +10,6 @@ cmake --version
gcc -v
tx --version
-# vcpkg needs these: curl zip unzip tar, have tar
-apt-get install -y curl zip unzip
-
mkdir build && cd build
cmake .. -DENABLE_QT_TRANSLATION=ON -DGENERATE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_SDL2=OFF -DYUZU_TESTS=OFF -DYUZU_USE_BUNDLED_VCPKG=ON
make translation
diff --git a/.ci/scripts/windows/docker.sh b/.ci/scripts/windows/docker.sh
index 6f522feed..0be3613aa 100755
--- a/.ci/scripts/windows/docker.sh
+++ b/.ci/scripts/windows/docker.sh
@@ -10,13 +10,9 @@ set -e
ccache -sv
mkdir -p build && cd build
-export LDFLAGS="-fuse-ld=lld"
-# -femulated-tls required due to an incompatibility between GCC and Clang
-# TODO(lat9nq): If this is widespread, we probably need to add this to CMakeLists where appropriate
-export CXXFLAGS="-femulated-tls"
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
- -DCMAKE_TOOLCHAIN_FILE="${PWD}/../CMakeModules/MinGWClangCross.cmake" \
+ -DCMAKE_TOOLCHAIN_FILE="${PWD}/../CMakeModules/MinGWCross.cmake" \
-DDISPLAY_VERSION="$1" \
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
-DENABLE_QT_TRANSLATION=ON \
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index aa5824824..25ef1f078 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -19,11 +19,11 @@ jobs:
- uses: actions/checkout@v3
with:
submodules: recursive
- fetch-depth: 0
+ fetch-depth: 0
- name: Update Translation
run: ./.ci/scripts/transifex/docker.sh
env:
- TRANSIFEX_API_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
+ TX_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
reuse:
runs-on: ubuntu-latest
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 20dd1383f..b625743ea 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -252,7 +252,7 @@ if(ENABLE_QT)
endif()
# Check for headers
- Include(FindPkgConfig REQUIRED)
+ find_package(PkgConfig REQUIRED)
pkg_check_modules(QT_DEP_GLU QUIET glu>=9.0.0)
if (NOT QT_DEP_GLU_FOUND)
message(FATAL_ERROR "Qt bundled pacakge dependency `glu` not found. \
@@ -386,7 +386,7 @@ endif()
# Ensure libusb is properly configured (based on dolphin libusb include)
if(NOT APPLE AND NOT YUZU_USE_BUNDLED_LIBUSB)
- include(FindPkgConfig)
+ find_package(PkgConfig)
if (PKG_CONFIG_FOUND AND NOT CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD")
pkg_check_modules(LIBUSB QUIET libusb-1.0>=1.0.24)
else()
@@ -410,7 +410,7 @@ set(FFmpeg_COMPONENTS
swscale)
if (UNIX AND NOT APPLE)
- Include(FindPkgConfig REQUIRED)
+ find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBVA libva)
endif()
if (NOT YUZU_USE_BUNDLED_FFMPEG)
@@ -541,9 +541,9 @@ add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY
# Adjustments for MSVC + Ninja
if (MSVC AND CMAKE_GENERATOR STREQUAL "Ninja")
add_compile_options(
- /wd4711 # function 'function' selected for automatic inline expansion
/wd4464 # relative include path contains '..'
- /wd4820 # 'identifier1': '4' bytes padding added after data member 'identifier2'
+ /wd4711 # function 'function' selected for automatic inline expansion
+ /wd4820 # 'bytes' bytes padding added after construct 'member_name'
)
endif()
diff --git a/CMakeModules/GenerateSCMRev.cmake b/CMakeModules/GenerateSCMRev.cmake
index 0e4bd121c..2cdb9189a 100644
--- a/CMakeModules/GenerateSCMRev.cmake
+++ b/CMakeModules/GenerateSCMRev.cmake
@@ -7,11 +7,6 @@ function(get_timestamp _var)
set(${_var} "${timestamp}" PARENT_SCOPE)
endfunction()
-list(APPEND CMAKE_MODULE_PATH "${SRC_DIR}/externals/cmake-modules")
-
-# Find the package here with the known path so that the GetGit commands can find it as well
-find_package(Git QUIET PATHS "${GIT_EXECUTABLE}")
-
# generate git/build information
include(GetGitRevisionDescription)
if(NOT GIT_REF_SPEC)
@@ -29,6 +24,7 @@ get_timestamp(BUILD_DATE)
# Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well
set(REPO_NAME "")
set(BUILD_VERSION "0")
+set(BUILD_ID ${DISPLAY_VERSION})
if (BUILD_REPOSITORY)
# regex capture the string nightly or canary into CMAKE_MATCH_1
string(REGEX MATCH "yuzu-emu/yuzu-?(.*)" OUTVAR ${BUILD_REPOSITORY})
@@ -57,6 +53,4 @@ if (BUILD_REPOSITORY)
endif()
endif()
-# The variable SRC_DIR must be passed into the script
-# (since it uses the current build directory for all values of CMAKE_*_DIR)
-configure_file("${SRC_DIR}/src/common/scm_rev.cpp.in" "scm_rev.cpp" @ONLY)
+configure_file(scm_rev.cpp.in scm_rev.cpp @ONLY)
diff --git a/dist/icons/controller/applet_pro_controller_dark_disabled.png b/dist/icons/controller/applet_pro_controller_dark_disabled.png
index 416e1e2fb..d45f91db5 100644
--- a/dist/icons/controller/applet_pro_controller_dark_disabled.png
+++ b/dist/icons/controller/applet_pro_controller_dark_disabled.png
Binary files differ
diff --git a/dist/icons/controller/applet_pro_controller_disabled.png b/dist/icons/controller/applet_pro_controller_disabled.png
index 72a549ea9..8c6bcd308 100644
--- a/dist/icons/controller/applet_pro_controller_disabled.png
+++ b/dist/icons/controller/applet_pro_controller_disabled.png
Binary files differ
diff --git a/dist/icons/controller/applet_pro_controller_midnight_disabled.png b/dist/icons/controller/applet_pro_controller_midnight_disabled.png
index 2907f3be4..d27dbfc66 100644
--- a/dist/icons/controller/applet_pro_controller_midnight_disabled.png
+++ b/dist/icons/controller/applet_pro_controller_midnight_disabled.png
Binary files differ
diff --git a/dist/icons/overlay/button_A.png b/dist/icons/overlay/button_A.png
index fd90f8b42..aafafecff 100644
--- a/dist/icons/overlay/button_A.png
+++ b/dist/icons/overlay/button_A.png
Binary files differ
diff --git a/dist/icons/overlay/button_B.png b/dist/icons/overlay/button_B.png
index e8927addc..4a19d8176 100644
--- a/dist/icons/overlay/button_B.png
+++ b/dist/icons/overlay/button_B.png
Binary files differ
diff --git a/dist/icons/overlay/button_X.png b/dist/icons/overlay/button_X.png
index fe70fb685..f50a53974 100644
--- a/dist/icons/overlay/button_X.png
+++ b/dist/icons/overlay/button_X.png
Binary files differ
diff --git a/dist/icons/overlay/button_Y.png b/dist/icons/overlay/button_Y.png
index ca0de569d..435ec30d5 100644
--- a/dist/icons/overlay/button_Y.png
+++ b/dist/icons/overlay/button_Y.png
Binary files differ
diff --git a/dist/icons/overlay/button_press_stick.png b/dist/icons/overlay/button_press_stick.png
index 6d0254d50..13bbff9ef 100644
--- a/dist/icons/overlay/button_press_stick.png
+++ b/dist/icons/overlay/button_press_stick.png
Binary files differ
diff --git a/dist/icons/overlay/controller_dual_joycon.png b/dist/icons/overlay/controller_dual_joycon.png
index 8e8b5ad41..286b8d8aa 100644
--- a/dist/icons/overlay/controller_dual_joycon.png
+++ b/dist/icons/overlay/controller_dual_joycon.png
Binary files differ
diff --git a/dist/icons/overlay/controller_dual_joycon_dark.png b/dist/icons/overlay/controller_dual_joycon_dark.png
index 63e03eb4e..3fba54618 100644
--- a/dist/icons/overlay/controller_dual_joycon_dark.png
+++ b/dist/icons/overlay/controller_dual_joycon_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_handheld.png b/dist/icons/overlay/controller_handheld.png
index deb375011..38c38c0da 100644
--- a/dist/icons/overlay/controller_handheld.png
+++ b/dist/icons/overlay/controller_handheld.png
Binary files differ
diff --git a/dist/icons/overlay/controller_handheld_dark.png b/dist/icons/overlay/controller_handheld_dark.png
index 1f5317aa0..2b73b812e 100644
--- a/dist/icons/overlay/controller_handheld_dark.png
+++ b/dist/icons/overlay/controller_handheld_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_pro.png b/dist/icons/overlay/controller_pro.png
index 67cf86d5c..78273fe57 100644
--- a/dist/icons/overlay/controller_pro.png
+++ b/dist/icons/overlay/controller_pro.png
Binary files differ
diff --git a/dist/icons/overlay/controller_pro_dark.png b/dist/icons/overlay/controller_pro_dark.png
index 7be655b96..8d261f1f7 100644
--- a/dist/icons/overlay/controller_pro_dark.png
+++ b/dist/icons/overlay/controller_pro_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_left.png b/dist/icons/overlay/controller_single_joycon_left.png
index 340ddc71b..34f0a424e 100644
--- a/dist/icons/overlay/controller_single_joycon_left.png
+++ b/dist/icons/overlay/controller_single_joycon_left.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_left_dark.png b/dist/icons/overlay/controller_single_joycon_left_dark.png
index 24ed2c44c..740647a2b 100644
--- a/dist/icons/overlay/controller_single_joycon_left_dark.png
+++ b/dist/icons/overlay/controller_single_joycon_left_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_left_y_dark.png b/dist/icons/overlay/controller_single_joycon_left_y_dark.png
index fdf177c12..725bec62d 100644
--- a/dist/icons/overlay/controller_single_joycon_left_y_dark.png
+++ b/dist/icons/overlay/controller_single_joycon_left_y_dark.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_right.png b/dist/icons/overlay/controller_single_joycon_right.png
index 5b8fc0eff..65e7686ca 100644
--- a/dist/icons/overlay/controller_single_joycon_right.png
+++ b/dist/icons/overlay/controller_single_joycon_right.png
Binary files differ
diff --git a/dist/icons/overlay/controller_single_joycon_right_dark.png b/dist/icons/overlay/controller_single_joycon_right_dark.png
index afa80e6ef..81cb94a1d 100644
--- a/dist/icons/overlay/controller_single_joycon_right_dark.png
+++ b/dist/icons/overlay/controller_single_joycon_right_dark.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_backspace.png b/dist/icons/overlay/osk_button_backspace.png
index 4ad284720..b7dc33228 100644
--- a/dist/icons/overlay/osk_button_backspace.png
+++ b/dist/icons/overlay/osk_button_backspace.png
Binary files differ
diff --git a/dist/icons/overlay/osk_button_backspace_dark.png b/dist/icons/overlay/osk_button_backspace_dark.png
index 19ac8847e..542038bef 100644
--- a/dist/icons/overlay/osk_button_backspace_dark.png
+++ b/dist/icons/overlay/osk_button_backspace_dark.png
Binary files differ
diff --git a/dist/languages/.tx/config b/dist/languages/.tx/config
index 0d9b512ea..30e76b925 100644
--- a/dist/languages/.tx/config
+++ b/dist/languages/.tx/config
@@ -1,7 +1,7 @@
[main]
host = https://www.transifex.com
-[yuzu.emulator]
+[o:yuzu-emulator:p:yuzu:r:emulator]
file_filter = <lang>.ts
source_file = en.ts
source_lang = en
diff --git a/dist/languages/README.md b/dist/languages/README.md
index 61981ab1d..c5ea1ada0 100644
--- a/dist/languages/README.md
+++ b/dist/languages/README.md
@@ -1 +1,3 @@
-This directory stores translation patches (TS files) for yuzu Qt frontend. This directory is linked with [yuzu project on transifex](https://www.transifex.com/yuzu-emulator/yuzu), so you can update the translation by executing `tx pull -a`. If you want to contribute to the translation, please go the transifex link and submit your translation there. This directory on the main repo will be synchronized with transifex periodically. Do not directly open PRs on github to modify the translation.
+This directory stores translation patches (TS files) for yuzu Qt frontend. This directory is linked with [yuzu project on transifex](https://www.transifex.com/yuzu-emulator/yuzu), so you can update the translation by executing `tx pull -t -a`. If you want to contribute to the translation, please go the transifex link and submit your translation there. This directory on the main repo will be synchronized with transifex periodically.
+
+Do not directly open PRs on github to modify the translation.
diff --git a/dist/languages/ca.ts b/dist/languages/ca.ts
index 59f864f10..1d33bd89f 100644
--- a/dist/languages/ca.ts
+++ b/dist/languages/ca.ts
@@ -89,78 +89,78 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -763,200 +763,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Activar GDB Stub</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Port:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Registre</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Filtre de registre global</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Mostra el registre a la consola</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Obrir ubicació de l&apos;arxiu del registre</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Quan està marcat, la mida màxima del registre augmenta de 100 MB a 1 GB </translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Habilitar registre ampliat**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Cadena d&apos;arguments</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Gràfics</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Quan està marcat, l&apos;API de gràfics entrarà en un mode de depuració més lent</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Activar depuració de gràfics</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>Quan està marcat, habilitarà els volcats dels errors d&apos;Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Activar Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation>Quan està marcat, bolcarà tots els shaders d&apos;assemblador originals del cache de shaders del disc o del joc mentre els troba</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation>Bolcar shaders del joc</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>Quan està marcat, desactiva el compilador de macro Just In Time. Activar això fa que els jocs funcionin més lentament</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Desactivar macro JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>Quan està marcat, yuzu registrarà estadístiques sobre la cache de canonada compilada</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>Activar informació de shaders</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>Quan està marcat, s&apos;executaran els shaders sense canvis de lògica de bucle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>Desactivar comprovacions de seguretat de bucles</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Depuració</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>Activa els serveis d&apos;informes detallats**</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
<source>Enable FS Access Log</source>
<translation>Activar registre d&apos;accés al FS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
+ <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
- <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>Activa els serveis d&apos;informes detallats**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Avançat</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Mode quiosc (Quest)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Activar depuració de la CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Activar alertes de depuració</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>Activar Auto-Stub**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation>Activar tots els tipus de controladors</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Desactivar el Web Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Això es restablirà automàticament quan es tanqui yuzu.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1575,37 +1610,47 @@ This would ban both their forum username and their IP address.</source>
<translation>Utilitzar temps ràpid a la GPU (Hack)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Filtrat anisotròpic:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>Automàtic</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Valor predeterminat</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2097,7 +2142,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Palanca esquerra</translation>
</message>
@@ -2191,14 +2236,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2217,7 +2262,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Més</translation>
</message>
@@ -2230,15 +2275,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2295,231 +2340,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Palanca dreta</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Esborrar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[no establert]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Botó commutador</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>Botó d&apos;inversió</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Botó commutador</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Invertir eixos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>Configurar llindar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Esculli un valor entre 0% i 100%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation>Configurar llindar giroscopi</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Configuració de palanca analògica</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Després de prémer D&apos;acord, primer moveu el joystick horitzontalment i després verticalment.
Per invertir els eixos, primer moveu el joystick verticalment i després horitzontalment.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation>Centrar eixos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Zona morta: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Rang del modificador: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Controlador Pro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Joycons duals</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Joycon esquerra</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Joycon dret</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Portàtil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>Controlador de GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>Controlador NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>Controlador SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>Controlador N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Inici / Pausa</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Palanca de control</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Sacseja!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[esperant]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Nou perfil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Introdueixi un nom de perfil:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Crear perfil d&apos;entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>El nom de perfil introduït no és vàlid!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Error al crear el perfil d&apos;entrada &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Eliminar perfil d&apos;entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Error al eliminar el perfil d&apos;entrada &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Carregar perfil d&apos;entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Error al carregar el perfil d&apos;entrada &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Guardar perfil d&apos;entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Error al guardar el perfil d&apos;entrada &quot;%1&quot;</translation>
</message>
@@ -2774,42 +2824,42 @@ Per invertir els eixos, primer moveu el joystick verticalment i després horitzo
<translation>Desenvolupador</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Complements</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>General</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Gràfics</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Gràfics avanç.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Àudio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Propietats</translation>
</message>
@@ -3521,47 +3571,47 @@ Per invertir els eixos, primer moveu el joystick verticalment i després horitzo
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Llegeix l&apos;entrada dels controladors des dels scripts en el mateix format que els scripts TAS-nx.&lt;br/&gt;Per a una explicació més detallada, si us plau, consulti la &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;pàgina d&apos;ajuda&lt;/span&gt;&lt;/a&gt; a la pàgina web de yuzu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>Per a comprovar quines tecles d&apos;accés ràpid controlen la reproducció/gravació, si us plau, revisi la configuració de les tecles d&apos;accés ràpid (Configuració -&gt; General -&gt; Tecles d&apos;accés ràpid)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>AVÍS: Aquesta és una característica experimental.&lt;br/&gt;No es reproduiran els scripts perfectament amb l&apos;actual i imperfecte mètode de sincronització de cuadres.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Paràmetres</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>Activar funcionalitats TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>Repetir script en bucle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>Pausar execució durant les càrregues</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>Directori d&apos;scripts</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Ruta</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3971,7 +4021,7 @@ Arrossegui els punts per a canviar la posició, o faci doble clic a les cel·les
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Verificar</translation>
</message>
@@ -4058,7 +4108,7 @@ Arrossegui els punts per a canviar la posició, o faci doble clic a les cel·les
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Sense especificar</translation>
</message>
@@ -4073,17 +4123,36 @@ Arrossegui els punts per a canviar la posició, o faci doble clic a les cel·les
<translation>El token no ha sigut verificat. El canvi al seu token no s&apos;ha guardat.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Comprovant...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Verificació fallida</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Verificació fallida</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Verificació fallida. Comprovi que hagi ingressat el seu token correctament, i que la seva connexió a internet estigui funcionant.</translation>
</message>
@@ -4152,12 +4221,12 @@ Arrossegui els punts per a canviar la posició, o faci doble clic a les cel·les
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation type="unfinished"/>
</message>
@@ -4165,488 +4234,488 @@ Arrossegui els punts per a canviar la posició, o faci doble clic a les cel·les
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Es recullen dades anònimes&lt;/a&gt; per ajudar a millorar yuzu. &lt;br/&gt;&lt;br/&gt;Desitja compartir les seves dades d&apos;ús amb nosaltres?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Carregant Web applet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Desactivar el Web Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Desactivar l&apos;Applet Web pot provocar comportaments indefinits i només hauria d&apos;utilitzar-se amb Super Mario 3D All-Stars. Estàs segur de que vols desactivar l&apos;Applet Web?
(Això pot ser reactivat als paràmetres Debug.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>La quantitat de shaders que s&apos;estan compilant actualment</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>El multiplicador d&apos;escala de resolució seleccionat actualment.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Velocitat d&apos;emulació actual. Valors superiors o inferiors a 100% indiquen que l&apos;emulació s&apos;està executant més ràpidament o més lentament que a la Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Quants fotogrames per segon està mostrant el joc actualment. Això variarà d&apos;un joc a un altre i d&apos;una escena a una altra.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Temps que costa emular un fotograma de la Switch, sense tenir en compte la limitació de fotogrames o la sincronització vertical. Per a una emulació òptima, aquest valor hauria de ser com a màxim de 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Esborrar arxius recents</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>&amp;Continuar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Pausar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>yuzu està executant un joc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Advertència format del joc desfasat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Està utilitzant el format de directori de ROM deconstruït per a aquest joc, que és un format desactualitzat que ha sigut reemplaçat per altres, com NCA, NAX, XCI o NSP. Els directoris de ROM deconstruïts careixen d&apos;icones, metadades i suport d&apos;actualitzacions.&lt;br&gt;&lt;br&gt;Per a obtenir una explicació dels diversos formats de Switch que suporta yuzu,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;faci una ullada a la nostra wiki&lt;/a&gt;. Aquest missatge no es tornarà a mostrar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Error carregant la ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>El format de la ROM no està suportat.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>S&apos;ha produït un error inicialitzant el nucli de vídeo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu ha trobat un error mentre executava el nucli de vídeo. Això sol ser causat per controladors de la GPU obsolets, inclosos els integrats. Si us plau, consulti el registre per a més detalls. Per obtenir més informació sobre com accedir al registre, consulti la següent pàgina: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Com carregar el fitxer de registre&lt;/a&gt;. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Error al carregar la ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Si us plau, segueixi &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;la guia d&apos;inici de yuzu&lt;/a&gt; per a bolcar de nou els seus fitxers.&lt;br&gt;Pot consultar la wiki de yuzu wiki&lt;/a&gt; o el Discord de yuzu&lt;/a&gt; per obtenir ajuda.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>S&apos;ha produït un error desconegut. Si us plau, consulti el registre per a més detalls.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Dades de partides guardades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Dades de mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Error obrint la carpeta %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>La carpeta no existeix!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Error obrint la cache transferible de shaders</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>No s&apos;ha pogut crear el directori de la cache dels shaders per aquest títol.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Continguts</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Actualització</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Eliminar entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>Eliminar el joc instal·lat %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>S&apos;ha eliminat correctament</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>S&apos;ha eliminat correctament el joc base instal·lat.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>Error eliminant %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>El joc base no està instal·lat a la NAND i no pot ser eliminat.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>S&apos;ha eliminat correctament l&apos;actualització instal·lada.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>No hi ha cap actualització instal·lada per aquest títol.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>No hi ha cap DLC instal·lat per aquest títol.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>S&apos;ha eliminat correctament %1 DLC instal·lat/s.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Desitja eliminar la cache transferible de shaders d&apos;OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Desitja eliminar la cache transferible de shaders de Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Desitja eliminar totes les caches transferibles de shaders?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>Desitja eliminar la configuració personalitzada del joc?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Eliminar arxiu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Error eliminant la cache transferible de shaders</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>No existeix una cache de shaders per aquest títol.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>S&apos;ha eliminat correctament la cache transferible de shaders.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>No s&apos;ha pogut eliminar la cache transferible de shaders.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Error al eliminar les caches de shaders transferibles</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Caches de shaders transferibles eliminades correctament.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>No s&apos;ha pogut eliminar el directori de caches de shaders transferibles.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Error eliminant la configuració personalitzada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>No existeix una configuració personalitzada per aquest joc.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>S&apos;ha eliminat correctament la configuració personalitzada del joc.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>No s&apos;ha pogut eliminar la configuració personalitzada del joc.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>La extracció de RomFS ha fallat!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>S&apos;ha produït un error copiant els arxius RomFS o l&apos;usuari ha cancel·lat la operació.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Completa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Esquelet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Seleccioni el mode de bolcat de RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Si us plau, seleccioni la forma en que desitja bolcar la RomFS.&lt;br&gt;Completa copiarà tots els arxius al nou directori mentre que&lt;br&gt;esquelet només crearà l&apos;estructura de directoris.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>No hi ha suficient espai lliure a %1 per extreure el RomFS. Si us plau, alliberi espai o esculli un altre directori de bolcat a Emulació &gt; Configuració &gt; Sistema &gt; Sistema d&apos;arxius &gt; Carpeta arrel de bolcat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Extraient RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Cancel·la</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Extracció de RomFS completada correctament!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>L&apos;operació s&apos;ha completat correctament.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Error obrint %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Seleccionar directori</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Propietats</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Les propietats del joc no s&apos;han pogut carregar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Executable de Switch (%1);;Tots els Arxius (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Carregar arxiu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Obrir el directori de la ROM extreta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Directori seleccionat invàlid</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>El directori que ha seleccionat no conté un arxiu &apos;main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Arxiu de Switch Instal·lable (*.nca *.nsp *.xci);;Arxiu de Continguts Nintendo (*.nca);;Paquet d&apos;enviament Nintendo (*.nsp);;Imatge de Cartutx NX (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Instal·lar arxius</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n arxiu(s) restants</numerusform><numerusform>%n arxiu(s) restants</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Instal·lant arxiu &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Resultats instal·lació</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Per evitar possibles conflictes, no recomanem als usuaris que instal·lin jocs base a la NAND.
Si us plau, utilitzi aquesta funció només per a instal·lar actualitzacions i DLCs.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n nou(s) arxiu(s) s&apos;ha(n) instal·lat
@@ -4654,7 +4723,7 @@ Si us plau, utilitzi aquesta funció només per a instal·lar actualitzacions i
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n arxiu(s) s&apos;han sobreescrit
@@ -4662,7 +4731,7 @@ Si us plau, utilitzi aquesta funció només per a instal·lar actualitzacions i
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n arxiu(s) no s&apos;han instal·lat
@@ -4670,411 +4739,391 @@ Si us plau, utilitzi aquesta funció només per a instal·lar actualitzacions i
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Aplicació del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Arxiu del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Actualització de l&apos;aplicació del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Paquet de firmware (Tipus A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Paquet de firmware (Tipus B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Joc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Actualització de joc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>DLC del joc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Títol delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Seleccioni el tipus d&apos;instal·lació NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Seleccioni el tipus de títol que desitja instal·lar aquest NCA com a:
(En la majoria dels casos, el valor predeterminat &apos;Joc&apos; està bé.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Ha fallat la instal·lació</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>El tipus de títol seleccionat per el NCA és invàlid.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Arxiu no trobat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Arxiu &quot;%1&quot; no trobat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>D&apos;acord</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Falta el compte de yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Per tal d&apos;enviar un cas de prova de compatibilitat de joc, ha de vincular el seu compte de yuzu.&lt;br&gt;&lt;br/&gt;Per a vincular el seu compte de yuzu, vagi a Emulació &amp; gt; Configuració &amp; gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Error obrint URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>No es pot obrir la URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>Gravació TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>Sobreescriure l&apos;arxiu del jugador 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>Configuració invàlida detectada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>El controlador del mode portàtil no es pot fer servir en el mode acoblat. Es seleccionarà el controlador Pro en el seu lloc.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation>El joc actual no està buscant amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation>L&apos;amiibo actual ha sigut eliminat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Arxiu Amiibo (%1);; Tots els Arxius (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Carregar Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Error obrint l&apos;arxiu de dades d&apos;Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>No s&apos;ha pogut obrir l&apos;arxiu de dades d&apos;Amiibo &quot;%1&quot; per a lectura.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Error llegint l&apos;arxiu de dades d&apos;Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>No s&apos;han pogut llegir completament les dades d&apos;Amiibo. S&apos;esperava llegir %1 bytes, però només s&apos;han pogut llegir %2 bytes.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Error al carregar les dades d&apos;Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>No s&apos;han pogut carregar les dades d&apos;Amiibo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Captura de pantalla</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>Imatge PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>Estat TAS: executant %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>Estat TAS: gravant %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>Estat TAS: inactiu %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>Estat TAS: invàlid</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>&amp;Parar l&apos;execució</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Iniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>Parar g&amp;ravació</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>G&amp;ravar</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Construint: %n shader(s)</numerusform><numerusform>Construint: %n shader(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Escala: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Velocitat: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Velocitat: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Joc: %1 FPS (desbloquejat)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Joc: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Fotograma: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU ALTA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU EXTREMA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>ERROR GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>MÉS PROPER</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>BILINEAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>BICÚBIC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>GAUSSIÀ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>SENSE AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>El joc que està intentant carregar requereix d&apos;arxius addicionals de la seva Switch abans de poder jugar. &lt;br/&gt;&lt;br/&gt;Per a obtenir més informació sobre com bolcar aquests arxius, vagi a la següent pàgina de la wiki: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Bolcar arxius del sistema i les fonts compartides des d&apos;una Consola Switch&lt;/a&gt;. &lt;br/&gt;&lt;br/&gt;Desitja tornar a la llista de jocs? Continuar amb l&apos;emulació pot provocar el tancament inesperat, dades de partides guardades corruptes o altres errors.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>yuzu no ha pogut localitzar l&apos;arxiu de sistema de la Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>yuzu no ha pogut localitzar un arxiu de sistema de la Switch: %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Arxiu del sistema no trobat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Falta arxiu del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu no ha pogut trobar les fonts compartides de la Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Fonts compartides no trobades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Falten les fonts compartides</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Error fatal</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu ha trobat un error fatal, consulti el registre per a obtenir més detalls. Per a més informació sobre com accedir al registre, consulti la següent pàgina: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Com carregar l&apos;arxiu de registre?&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt; Desitja tornar al llistat de jocs? Continuar amb l&apos;emulació pot provocar el tancament inesperat, dades de partides guardades corruptes o altres errors.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Trobat error fatal</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Confirmi la clau de rederivació</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5091,37 +5140,37 @@ i opcionalment faci còpies de seguretat.
Això eliminarà els arxius de les claus generats automàticament i tornarà a executar el mòdul de derivació de claus.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>Falten fusibles</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation> - Falta BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - Falta BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation> - Falta PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>Falten components de derivació</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Falten les claus d&apos;encriptació. &lt;br&gt;Si us plau, segueixi &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;la guia ràpida de yuzu&lt;/a&gt; per a obtenir totes les seves claus, firmware i jocs.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5130,39 +5179,39 @@ Això pot prendre fins a un minut depenent
del rendiment del seu sistema.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Derivant claus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Seleccioni el destinatari per a bolcar el RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Si us plau, seleccioni quin RomFS desitja bolcar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Està segur de que vol tancar yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Està segur de que vol aturar l&apos;emulació? Qualsevol progrés no guardat es perdrà.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5544,12 +5593,12 @@ d&apos;inici.</translation>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5558,11 +5607,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5584,112 +5634,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Captura de pantalla</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Pantalla Completa</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Carregar arxiu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5804,42 +5853,42 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Jugadors</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation type="unfinished"/>
</message>
@@ -6166,7 +6215,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Connectat</translation>
</message>
@@ -6188,7 +6237,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation type="unfinished"/>
</message>
@@ -6292,22 +6341,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6315,7 +6381,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>Error</translation>
</message>
@@ -6374,7 +6440,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation type="unfinished"/>
</message>
@@ -6429,7 +6495,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[no establert]</translation>
</message>
@@ -6444,10 +6510,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Eix %1%2</translation>
</message>
@@ -6461,9 +6527,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[desconegut]</translation>
</message>
@@ -6628,15 +6694,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[invàlid]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation>%1%2Rotació %3</translation>
</message>
@@ -6644,35 +6710,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation>%1%2Eix %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation>%1%2Eixos %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2Moviment %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2Botó %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[sense ús]</translation>
</message>
@@ -6713,7 +6779,7 @@ p, li { white-space: pre-wrap; }
<translation>Extra</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/languages/cs.ts b/dist/languages/cs.ts
index cc83592a8..118bb0299 100644
--- a/dist/languages/cs.ts
+++ b/dist/languages/cs.ts
@@ -89,78 +89,78 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -755,200 +755,235 @@ Tato možnost zlepšuje rychlost díky závislosti na sémantice cmpxchg pro zaj
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation>Debugger</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Povolit GDB Stub</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Port:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Logování</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Centrální log filtr</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Zobrazit log v konzoli</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Otevřít lokaci s logama</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Po povolení se zvýší maximální velikost logu z 100 MB na 1 GB.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Povolit rozšířené logování</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Argumenty</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Grafika</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Po povolení se grafické API přepne do pomalejšího režimu ladění.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Zapnout ladění grafiky</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>Zaškrtnutí povolí crash dumpy Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Povolit Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation>Když je zaškrtnuto, dumpne všechny originální shadery assembleru z diskové zálohy shaderů či hry jak jsou nalezeny.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation>Dumpnout shadery hry</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation>Když je zaškrtnuto, dumpne všechny makro programy GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation>Dumpnout Maxwell Makra</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>Po povolení se zakáže makro Just-in-Time překladač. Poté hry poběží pomaleji.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Zakázat Makro JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>Když je zaškrtnuto, yuzu bude logovat statistiky o kompilované mezipaměti pipelinu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>Povolit Shader Feedback</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>Když je zaškrtnuto, shadery budou exekutovány bez změn logických smyček.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Ladění</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
- <source>Enable FS Access Log</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Pokročilé</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Předváděcí (Quest/Kiosk) režim</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Povolit Debug Asserts</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Zakázat Web Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation type="unfinished"/>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1567,37 +1602,47 @@ Tato možnost zlepšuje rychlost díky závislosti na sémantice cmpxchg pro zaj
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Anizotropní filtrování:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Výchozí</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2089,7 +2134,7 @@ Tato možnost zlepšuje rychlost díky závislosti na sémantice cmpxchg pro zaj
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Levá Páčka</translation>
</message>
@@ -2183,14 +2228,14 @@ Tato možnost zlepšuje rychlost díky závislosti na sémantice cmpxchg pro zaj
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2209,7 +2254,7 @@ Tato možnost zlepšuje rychlost díky závislosti na sémantice cmpxchg pro zaj
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Plus</translation>
</message>
@@ -2222,15 +2267,15 @@ Tato možnost zlepšuje rychlost díky závislosti na sémantice cmpxchg pro zaj
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2287,231 +2332,236 @@ Tato možnost zlepšuje rychlost díky závislosti na sémantice cmpxchg pro zaj
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Pravá páčka</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Vyčistit</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[nenastaveno]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Přepnout tlačítko</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Přepnout tlačítko</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Převrátit osy</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Namapovat analogovou páčku</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Po stisknutí OK nejprve posuňte joystick horizontálně, poté vertikálně.
Pro převrácení os nejprve posuňte joystick vertikálně, poté horizontálně.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Deadzone: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Rozsah modifikátoru: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Dual Joycons</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Levý Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Pravý Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>V rukou</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>Ovladač GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Start / Pause</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Control Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Shake!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[čekání]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Nový profil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Zadejte název profilu:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Vytvořit profil vstupu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>Zadaný název profilu není platný!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Nepodařilo se vytvořit profil vstupu &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Odstranit profil vstupu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Nepodařilo se odstranit profil vstupu &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Načíst profil vstupu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Nepodařilo se načíst profil vstupu &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Uložit profil vstupu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Nepodařilo se uložit profil vstupu &quot;%1&quot;</translation>
</message>
@@ -2766,42 +2816,42 @@ Pro převrácení os nejprve posuňte joystick vertikálně, poté horizontáln
<translation>Vývojář</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Doplňky</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Obecné</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Systém</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Grafika</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Pokroč. grafika</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Zvuk</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Vlastnosti</translation>
</message>
@@ -3513,47 +3563,47 @@ Pro převrácení os nejprve posuňte joystick vertikálně, poté horizontáln
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Nastavení</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Cesta</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3963,7 +4013,7 @@ Táhněte body pro změnu pozice nebo dvojitě klikněte na buňky tabulky pro z
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Ověřit</translation>
</message>
@@ -4050,7 +4100,7 @@ Táhněte body pro změnu pozice nebo dvojitě klikněte na buňky tabulky pro z
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Nespecifikovaný</translation>
</message>
@@ -4065,17 +4115,36 @@ Táhněte body pro změnu pozice nebo dvojitě klikněte na buňky tabulky pro z
<translation>Token nebyl ověřen. Změna k vašemu tokenu nebyla uložena.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Ověřuji...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Ověřování selhalo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Ověřování selhalo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Ověřování selhalo. Zkontrolujte, zda jste zadali token správně a že vaše připojení k internetu funguje v pořádku.</translation>
</message>
@@ -4144,12 +4213,12 @@ Táhněte body pro změnu pozice nebo dvojitě klikněte na buňky tabulky pro z
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation type="unfinished"/>
</message>
@@ -4157,909 +4226,889 @@ Táhněte body pro změnu pozice nebo dvojitě klikněte na buňky tabulky pro z
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymní data jsou sbírána&lt;/a&gt; pro vylepšení yuzu. &lt;br/&gt;&lt;br/&gt;Chcete s námi sdílet anonymní data?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Načítání Web Appletu...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Zakázat Web Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>Počet aktuálně sestavovaných shaderů</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Aktuální emulační rychlost. Hodnoty vyšší než 100% indikují, že emulace běží rychleji nebo pomaleji než na Switchi.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Kolik snímků za sekundu aktuálně hra zobrazuje. Tohle závisí na hře od hry a scény od scény.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Čas potřebný na emulaci framu scény, nepočítá se limit nebo v-sync. Pro plnou rychlost by se tohle mělo pohybovat okolo 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Vymazat poslední soubory</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>&amp;Pokračovat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Pauza</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Varování Zastaralý Formát Hry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Používáte rozbalený formát hry, který je zastaralý a byl nahrazen jinými jako NCA, NAX, XCI, nebo NSP. Rozbalená ROM nemá ikony, metadata, a podporu updatů.&lt;br&gt;&lt;br&gt;Pro vysvětlení všech možných podporovaných typů, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;zkoukni naší wiki&lt;/a&gt;. Tato zpráva se nebude znova zobrazovat.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Chyba při načítání ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>Tento formát ROM není podporován.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Nastala chyba při inicializaci jádra videa.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Chyba při načítání ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Pro extrakci souborů postupujte podle &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;rychlého průvodce yuzu&lt;/a&gt;. Nápovědu naleznete na &lt;br&gt;wiki&lt;/a&gt; nebo na Discordu&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Nastala chyba. Koukni do logu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Uložit data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Módovat Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Chyba otevírání složky %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Složka neexistuje!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Chyba při otevírání přenositelné mezipaměti shaderů</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Obsah</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Aktualizace</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Odebrat položku</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>Odebrat Nainstalovanou Hru %1? </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>Úspěšně odebráno</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>Úspěšně odebrán nainstalovaný základ hry.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>Chyba při odstraňování %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Základ hry není nainstalovaný na NAND a nemůže být odstraněn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>Úspěšně odebrána nainstalovaná aktualizace.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>Není nainstalovaná žádná aktualizace pro tento titul.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>Není nainstalované žádné DLC pro tento titul.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Úspěšně odstraněno %1 nainstalovaných DLC.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>Odstranit vlastní konfiguraci hry?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Odstranit soubor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Chyba při odstraňování přenositelné mezipaměti shaderů</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>Mezipaměť shaderů pro tento titul neexistuje.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Přenositelná mezipaměť shaderů úspěšně odstraněna</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Nepodařilo se odstranit přenositelnou mezipaměť shaderů</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Chyba při odstraňování vlastní konfigurace hry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Vlastní konfigurace hry pro tento titul neexistuje.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Úspěšně odstraněna vlastní konfigurace hry.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Nepodařilo se odstranit vlastní konfiguraci hry.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>Extrakce RomFS se nepovedla!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Nastala chyba při kopírování RomFS souborů, nebo uživatel operaci zrušil.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Plný</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Kostra</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Vyber RomFS Dump Mode</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Vyber jak by si chtěl RomFS vypsat.&lt;br&gt;Plné zkopíruje úplně všechno, ale&lt;br&gt;kostra zkopíruje jen strukturu složky.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Extrahuji RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Zrušit</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Extrakce RomFS se povedla!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>Operace byla dokončena úspěšně.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Chyba při otevírání %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Vybraná Složka</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Vlastnosti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Herní vlastnosti nemohly být načteny.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch Executable (%1);;Všechny soubory (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Načíst soubor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Otevřít složku s extrahovanou ROM</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Vybraná složka je neplatná</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Složka kterou jste vybrali neobsahuje soubor &quot;main&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Instalovatelný soubor pro Switch (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Instalovat Soubory</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Instalování souboru &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Výsledek instalace</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Abychom předešli možným konfliktům, nedoporučujeme uživatelům instalovat základní hry na paměť NAND.
Tuto funkci prosím používejte pouze k instalaci aktualizací a DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Systémová Aplikace</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Systémový archív</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Systémový Update Aplikace</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Firmware-ový baliček (Typu A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Firmware-ový baliček (Typu B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Hra</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Update Hry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>Herní DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Delta Title</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Vyberte typ instalace NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Vyberte typ title-u, který chcete nainstalovat tenhle NCA jako:
(Většinou základní &quot;game&quot; stačí.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Chyba v instalaci</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Tento typ pro tento NCA není platný.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Soubor nenalezen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Soubor &quot;%1&quot; nenalezen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Chybí účet yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Pro přidání recenze kompatibility je třeba mít účet yuzu&lt;br&gt;&lt;br/&gt;Pro nalinkování yuzu účtu jdi do Emulace &amp;gt; Konfigurace &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Chyba při otevírání URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Nelze otevřít URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>Zjištěno neplatné nastavení</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Ruční ovladač nelze používat v dokovacím režimu. Bude vybrán ovladač Pro Controller.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Soubor Amiibo (%1);; Všechny Soubory (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Načíst Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Chyba při načítání souboru Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Amiibo &quot;%1&quot; nešlo otevřít v řežimu pro čtení.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Chyba načítání Amiiba</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Načtení celého Amiiba nebylo možné. Očekáváno bylo %1 bytů, ale pouze %2 bytů se načetlo.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Chyba načítání Amiiba</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Načtení Amiiba nebylo možné</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Pořídit Snímek Obrazovky</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>PNG Image (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Rychlost: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Rychlost: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Hra: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Frame: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMÁLNÍ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU VYSOKÝ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU EXTRÉMNÍ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>GPU ERROR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>Hra, kterou se snažíte načíst potřebuje další data z vašeho Switche, než bude moci být načtena.&lt;br/&gt;&lt;br/&gt;Pro více informací o získání těchto souboru se koukněte na wiki: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Získávání Systémových Archivů a Sdílených Fontu z konzole Switch&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Přejete si odejít do listu her? Pokračování v emulaci by mohlo mít negativní účinky jako crashe, rozbité savy , nebo další bugy.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>Aplikace yuzu nenašla systémový archiv Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>Aplikace yuzu nenašla systémový archiv Switch: %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Systémový Archív Nenalezen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Chybí systémový archiv</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>Aplikace yuzu nenašla sdílená písma Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Sdílené Fonty Nenalezeny</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Chybí sdílené písmo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Fatální Chyba</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu narazilo na fatální chybu, prosím kouknšte do logu pro více informací. Pro více informací jak se dostat do logu se koukněte na následující stránku: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt; Jak Uploadnout Log&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Přejete si odejít do listu her? Pokračování v emulaci může mít za následek crashe, rozbité savy, nebo další bugy.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Vyskytla se kritická chyba</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Potvďte Rederivaci Klíčů</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5076,37 +5125,37 @@ a udělejte si zálohu.
Toto vymaže věechny vaše automaticky generované klíče a znova spustí modul derivace klíčů.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>Chybí Fuses</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation>- Chybí BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - Chybí BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation> - Chybí PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>Chybé odvozené komponenty</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5115,39 +5164,39 @@ Tohle může zabrat až minutu
podle výkonu systému.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Derivuji Klíče</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Vyberte Cíl vypsaní RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Vyberte, kterou RomFS chcete vypsat.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Jste si jist, že chcete zavřít yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Jste si jist, že chcete ukončit emulaci? Jakýkolic neuložený postup bude ztracen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5525,12 +5574,12 @@ Screen.</source>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5539,11 +5588,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5565,112 +5615,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Pořídit Snímek Obrazovky</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Celá Obrazovka</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Načíst soubor</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5784,42 +5833,42 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Hráči</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation type="unfinished"/>
</message>
@@ -6146,7 +6195,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Připojeno</translation>
</message>
@@ -6168,7 +6217,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation type="unfinished"/>
</message>
@@ -6272,22 +6321,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6295,7 +6361,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
@@ -6354,7 +6420,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation type="unfinished"/>
</message>
@@ -6409,7 +6475,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[Nenastaveno]</translation>
</message>
@@ -6424,10 +6490,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Osa %1%2</translation>
</message>
@@ -6441,9 +6507,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[Neznámá]</translation>
</message>
@@ -6608,15 +6674,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation type="unfinished"/>
</message>
@@ -6624,35 +6690,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[nepoužito]</translation>
</message>
@@ -6693,7 +6759,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation type="unfinished"/>
</message>
diff --git a/dist/languages/da.ts b/dist/languages/da.ts
index b6dea2f0d..c7d8c7603 100644
--- a/dist/languages/da.ts
+++ b/dist/languages/da.ts
@@ -89,78 +89,78 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -754,200 +754,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Aktiver GDB Stub</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Port:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Logføring</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Globalt Logfilter</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Vis Log i Konsol</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Åbn Logplacering</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Når valgt, øges loggens maksimale størrelse fra 100 MB til 1 GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Aktivér Udvidet Logning**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Hjemmebrændt</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Argumentsstreng</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Grafik</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Når valgt, påbegynder grafik-APIen en langsommere fejlfindingstilstand</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Aktivér Grafik-Fejlfinding</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>Når valgt, aktiverer det Nsight Aftermath nedbruds-nedfældelser</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Aktivér Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>Når valgt, deaktiverer det makro-Just-In-Time-kompilatoren. Aktivering heraf får spil til, at køre langsommere</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Deaktivér Makro-JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>Når valgt, vil yuzu logføre statistikker om det kompilerede rørlinje-mellemlager</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>Aktivér Shader-Tilbagemelding</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>Når valgt, eksekverer den shadere, uden loop-logik-forandringer</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>Deaktivér Loop-sikkerhedskontrol</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Fejlfinding</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>Aktivér Vitterlig Rapporteringstjeneste</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
<source>Enable FS Access Log</source>
<translation>Aktivér FS-Tilgangslog</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
+ <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
- <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>Aktivér Vitterlig Rapporteringstjeneste</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Avanceret</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Kiosk (Rejse)-Tilstand</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Aktivér CPU-Fejlfinding</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Aktivér Fejlfindingshævdelser</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>Aktivér Automatisk Stub**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Deaktivér Net-Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Dette vil automatisk blive nulstillet, når yuzu lukkes.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1566,37 +1601,47 @@ This would ban both their forum username and their IP address.</source>
<translation>Brug Hurtig GPU-Tid (Hack)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Anisotropisk Filtrering:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Standard</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation type="unfinished"/>
</message>
@@ -2088,7 +2133,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Venstre Styrepind</translation>
</message>
@@ -2182,14 +2227,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2208,7 +2253,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Plus</translation>
</message>
@@ -2221,15 +2266,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2286,231 +2331,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Højre Styrepind</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Ryd</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[ikke indstillet]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Funktionsskifteknap</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Funktionsskifteknap</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Omvend akser</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>Angiv tærskel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Vælg en værdi imellem 0% og 100%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Tilsted Analog Pind</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Bevæg, efter tryk på OK, først din styrepind vandret og så lodret.
Bevæg, for at omvende akserne, først din styrepind lodret og så vandret.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
- <translation>Dødzone: 1%</translation>
+ <translation>Dødzone: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Forandringsrækkevidde: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Pro-Styringsenhed</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Dobbelt-Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Venstre Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Højre Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Håndholdt</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>GameCube-Styringsenhed</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Start / Pause</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Styrepind</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Pind</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Ryst!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[venter]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Ny Profil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Indtast et profilnavn:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Opret Input-Profil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>Det angivne profilnavn er ikke gyldigt!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Oprettelse af input-profil &quot;%1&quot; mislykkedes</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Slet Input-Profil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Sletning af input-profil &quot;%1&quot; mislykkedes</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Indlæs Input-Profil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Indlæsning af input-profil &quot;%1&quot; mislykkedes</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Gem Input-Profil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Lagring af input-profil &quot;%1&quot; mislykkedes</translation>
</message>
@@ -2765,42 +2815,42 @@ Bevæg, for at omvende akserne, først din styrepind lodret og så vandret.</tra
<translation>Udvikler</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Tilføjelser</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Generelt</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>System</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Grafik</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Lyd</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Egenskaber</translation>
</message>
@@ -3042,7 +3092,7 @@ Bevæg, for at omvende akserne, først din styrepind lodret og så vandret.</tra
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="182"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="238"/>
<source>Deadzone: %1%</source>
- <translation>Dødzone: 1%</translation>
+ <translation>Dødzone: %1%</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="262"/>
@@ -3512,47 +3562,47 @@ Bevæg, for at omvende akserne, først din styrepind lodret og så vandret.</tra
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Læser styringsenheds input fra skrift, i samme format som TAS-nx skrifter.&lt;br/&gt;Konsultér venligst &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;hjælp-siden&lt;/span&gt;&lt;/a&gt;, for en mere detaljeret forklaring, på yuzu-hjemmesiden.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>Referér venligst til Genvajstast-indstillingerne (Konfigurér -&gt; Generelt -&gt; Genvejstaster), for at kontrollere hvilke genvejstaster, der kontrollerer afspilning/optagelse.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>ADVARSEL: Dette er en eksperimentiel funktion.&lt;br/&gt;Det vil ikke afspille skrifter perfekt til billedet, med den aktuelle, uperfekte synkroniseringsmetode.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Indstillinger</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>Aktivér TAS-funktioner</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>Loop skrift</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>Sæt eksekvering på pause under indlæsninger</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>Skriftmappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Sti</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3962,7 +4012,7 @@ Træk punkter, for at skifte position, eller dobbeltklik i tabelceller, for at r
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Bekræft</translation>
</message>
@@ -4049,7 +4099,7 @@ Træk punkter, for at skifte position, eller dobbeltklik i tabelceller, for at r
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Uspecificeret </translation>
</message>
@@ -4064,17 +4114,36 @@ Træk punkter, for at skifte position, eller dobbeltklik i tabelceller, for at r
<translation>Token blev ikke bekræftet. Ændringen af dit token er ikke blevet gemt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Bekræfter...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Bekræftelse mislykkedes</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Bekræftelse mislykkedes</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Bekræftelse mislykkedes. Kontrollér at du har indtastet dit token korrekt, og at din internetforbindelse virker.</translation>
</message>
@@ -4143,12 +4212,12 @@ Træk punkter, for at skifte position, eller dobbeltklik i tabelceller, for at r
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation type="unfinished"/>
</message>
@@ -4156,907 +4225,887 @@ Træk punkter, for at skifte position, eller dobbeltklik i tabelceller, for at r
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonym data indsamles&lt;/a&gt;, for at hjælp med, at forbedre yuzu. &lt;br/&gt;&lt;br/&gt;Kunne du tænke dig, at dele dine brugsdata med os?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Indlæser Net-Applet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Deaktivér Net-Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Aktuel emuleringshastighed. Værdier højere eller lavere end 100% indikerer, at emulering kører hurtigere eller langsommere end en Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Advarsel, Forældet Spilformat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Fejl under indlæsning af ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>ROM-formatet understøttes ikke.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Der skete en fejl under initialisering af video-kerne.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Fejl ved Åbning af %1 Mappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Mappe eksisterer ikke!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS-Udpakning Mislykkedes!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Der skete en fejl ved kopiering af RomFS-filerne, eller brugeren afbrød opgaven.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Fuld</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Skelet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Vælg RomFS-Nedfældelsestilstand</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Udpakker RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Afbryd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS-Udpakning Lykkedes!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>Fuldførelse af opgaven lykkedes.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Fejl ved Åbning af %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Vælg Mappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Egenskaber</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Spil-egenskaberne kunne ikke indlæses.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch-Eksekverbar (%1);;Alle filer (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Indlæs Fil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Åbn Udpakket ROM-Mappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Ugyldig Mappe Valgt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Installér fil &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Systemapplikation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Systemarkiv</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Systemapplikationsopdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Firmwarepakke (Type A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Firmwarepakke (Type B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Spil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Spilopdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>Spiludvidelse</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Delta-Titel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Vælg NCA-Installationstype...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Installation mislykkedes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Fil ikke fundet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Fil &quot;%1&quot; ikke fundet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Manglende yuzu-Konto</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo-Fil (%1);; Alle Filer (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Indlæs Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Fejl ved åbning af Amiibo-datafil</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Ude af stand til, at åbne Amiibo-fil &quot;%1&quot; til indlæsning.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Fejl ved indlæsning af Amiibo-datafil</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Fejl ved indlæsning af Amiibo-data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Ude af stand til, at indlæse Amiibo-data.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Optag Skærmbillede</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>PNG-Billede (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Hastighed: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Hastighed: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Spil: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Billede: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>yuzu var ude af stand til, at lokalisere et Switch-systemarkiv. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>yuzu var ude af stand til, at lokalisere et Switch-systemarkiv. %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Systemarkiv Ikke Fundet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Systemarkiv Mangler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu var ude af stand til, at finde delte Switch-skrifttyper. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Delte Skrifttyper Ikke Fundet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Delte Skrifttyper Mangler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Fatal Fejl</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Stødte på Fatal Fejl</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5067,76 +5116,76 @@ This will delete your autogenerated key files and re-run the key derivation modu
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Er du sikker på, at du vil lukke yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Er du sikker på, at du vil stoppe emulereingen? Enhver ulagret data, vil gå tabt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5511,12 +5560,12 @@ Screen.</source>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5525,11 +5574,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5551,112 +5601,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Optag Skærmbillede</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Fuldskærm</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Indlæs Fil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5770,42 +5819,42 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Spillere</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation type="unfinished"/>
</message>
@@ -6132,7 +6181,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Tilsluttet</translation>
</message>
@@ -6154,7 +6203,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation type="unfinished"/>
</message>
@@ -6258,22 +6307,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6281,7 +6347,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
@@ -6336,7 +6402,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation type="unfinished"/>
</message>
@@ -6391,7 +6457,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[ikke indstillet]</translation>
</message>
@@ -6406,10 +6472,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Akse %1%2</translation>
</message>
@@ -6423,9 +6489,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[ukendt]</translation>
</message>
@@ -6590,15 +6656,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation type="unfinished"/>
</message>
@@ -6606,35 +6672,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[ubrugt]</translation>
</message>
@@ -6675,7 +6741,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation type="unfinished"/>
</message>
diff --git a/dist/languages/de.ts b/dist/languages/de.ts
index bb35ff231..b7299e34d 100644
--- a/dist/languages/de.ts
+++ b/dist/languages/de.ts
@@ -87,86 +87,86 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="40"/>
<source>Send Chat Message</source>
- <translation type="unfinished"/>
+ <translation>Chatnachricht senden</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="47"/>
<source>Send Message</source>
- <translation type="unfinished"/>
+ <translation>Nachricht senden</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
- <translation type="unfinished"/>
+ <translation>Mitglieder</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation>%1 ist beigetreten</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation>%1 ist gegangen</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation>%1 wurde gekickt</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation>%1 wurde gebannt</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation>%1 wurde entbannt</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation>Profil ansehen</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation>Spieler blockieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation>Kicken</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation>Bannen</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation>Spieler kicken</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation>Spieler bannen</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -206,7 +206,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="87"/>
<source>Disconnected</source>
- <translation type="unfinished"/>
+ <translation>Verbindung getrennt</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="100"/>
@@ -378,7 +378,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="14"/>
<source>Configure Infrared Camera</source>
- <translation type="unfinished"/>
+ <translation>Infrarotkamera konfigurieren</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="26"/>
@@ -393,7 +393,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="71"/>
<source>Input device:</source>
- <translation type="unfinished"/>
+ <translation>Eingabegerät:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="96"/>
@@ -461,7 +461,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu.ui" line="57"/>
<source>Paranoid (disables most optimizations)</source>
- <translation type="unfinished"/>
+ <translation>Paranoid (deaktiviert die meisten Optimierungen)</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu.ui" line="68"/>
@@ -751,200 +751,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation>Debugger</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>GDB-Stub aktivieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Port:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Logging</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Globaler Log-Filter</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Log in der Konsole zeigen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Log-Verzeichnis öffnen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Wenn diese Option aktiviert ist, erhöht sich die maximale Größe des Logs von 100 MB auf 1 GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
- <translation type="unfinished"/>
+ <translation>Erweitertes Logging aktivieren**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>String-Argumente</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Grafik</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Wenn diese Option aktiviert ist, wechselt die Grafik-API in einen langsameren Debug-Modus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Grafik-Debugging aktivieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Nsight Aftermath aktivieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>Diese Option deaktiviert den Macro-JIT-Compiler. Dies wird die Geschwindigkeit verringern.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Macro-JIT deaktivieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
- <translation type="unfinished"/>
+ <translation>Shader-Feedback aktivieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Debugging</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
<source>Enable FS Access Log</source>
<translation>FS-Zugriffslog aktivieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
+ <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
- <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Erweitert</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Kiosk(Quest)-Modus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>CPU Debugging aktivieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>aktiviere Debug-Meldungen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>Auto-Stub** aktivieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Deaktiviere die Web Applikation</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation type="unfinished"/>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation>Neustart erforderlich</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation>yuzu muss neugestartet werden, damit diese Einstellungen übernommen werden können. </translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1258,7 +1293,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_general.ui" line="95"/>
<source>Mute audio when in background</source>
- <translation type="unfinished"/>
+ <translation>Audio im Hintergrund stummschalten</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_general.ui" line="102"/>
@@ -1301,7 +1336,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="64"/>
<source>Shader Backend:</source>
- <translation type="unfinished"/>
+ <translation>Shader Backend:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="92"/>
@@ -1321,7 +1356,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="162"/>
<source>Use disk pipeline cache</source>
- <translation type="unfinished"/>
+ <translation>Disk-Pipeline-Cache verwenden</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="169"/>
@@ -1540,7 +1575,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="78"/>
<source>Use VSync</source>
- <translation type="unfinished"/>
+ <translation>VSync verwenden</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="85"/>
@@ -1563,37 +1598,47 @@ This would ban both their forum username and their IP address.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Anisotrope Filterung:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>Automatisch</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Standard</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -1638,7 +1683,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="98"/>
<source>Controller Hotkey</source>
- <translation type="unfinished"/>
+ <translation>Controller-Hotkey</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="138"/>
@@ -1988,12 +2033,12 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2609"/>
<source>Ring Controller</source>
- <translation type="unfinished"/>
+ <translation>Ring-Controller</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2623"/>
<source>Infrared Camera</source>
- <translation type="unfinished"/>
+ <translation>Infrarotkamera</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2640"/>
@@ -2023,7 +2068,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2694"/>
<source>Controller navigation</source>
- <translation type="unfinished"/>
+ <translation>Controller-Navigation</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2707"/>
@@ -2085,7 +2130,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Linker Analogstick</translation>
</message>
@@ -2179,14 +2224,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2205,7 +2250,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Plus</translation>
</message>
@@ -2218,15 +2263,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2283,231 +2328,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Rechter Analogstick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Löschen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[nicht belegt]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Taste umschalten</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>Knopf invertieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Taste umschalten</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Achsen umkehren</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Wert zwischen 0% und 100% wählen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Analog-Stick festlegen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Nach dem Drücken von OK den Joystick zuerst horizontal, dann vertikal bewegen.
Um die Achsen umzukehren, bewege den Joystick zuerst vertikal und dann horizontal.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
- <translation type="unfinished"/>
+ <translation>Achse zentrieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Deadzone: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Modifikator-Radius: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Zwei Joycons</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Linker Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Rechter Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Handheld</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>GameCube-Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>Poke-Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>NES Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>SNES Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>N64 Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Start / Pause</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Analog Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Schütteln!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[wartet]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Neues Profil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Profilnamen eingeben:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Eingabeprofil erstellen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>Angegebener Profilname ist nicht gültig!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Erstellen des Eingabeprofils &quot;%1&quot; ist fehlgeschlagen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Eingabeprofil löschen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Löschen des Eingabeprofils &quot;%1&quot; ist fehlgeschlagen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Eingabeprofil laden</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Laden des Eingabeprofils &quot;%1&quot; ist fehlgeschlagen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Eingabeprofil speichern</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Speichern des Eingabeprofils &quot;%1&quot; ist fehlgeschlagen</translation>
</message>
@@ -2762,42 +2812,42 @@ Um die Achsen umzukehren, bewege den Joystick zuerst vertikal und dann horizonta
<translation>Entwickler</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Add-Ons</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Allgemeines</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>System</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Grafik</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Erw. Grafik</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Audio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Einstellungen</translation>
</message>
@@ -2986,7 +3036,7 @@ Um die Achsen umzukehren, bewege den Joystick zuerst vertikal und dann horizonta
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="14"/>
<source>Configure Ring Controller</source>
- <translation type="unfinished"/>
+ <translation>Ring-Controller konfigurieren</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="26"/>
@@ -3002,13 +3052,13 @@ Um die Achsen umzukehren, bewege den Joystick zuerst vertikal und dann horizonta
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="84"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="123"/>
<source>Pull</source>
- <translation type="unfinished"/>
+ <translation>Ziehen</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="133"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="172"/>
<source>Push</source>
- <translation type="unfinished"/>
+ <translation>Drücken</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="206"/>
@@ -3509,47 +3559,47 @@ Um die Achsen umzukehren, bewege den Joystick zuerst vertikal und dann horizonta
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Einstellungen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
- <translation type="unfinished"/>
+ <translation>TAS-Funktionen aktivieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
- <translation type="unfinished"/>
+ <translation>Script loopen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>Skript-Verzeichnis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Pfad</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3724,7 +3774,7 @@ Ziehe die Punkte mit deiner Maus, um ihre Position zu ändern. Doppelklicke auf
<message>
<location filename="../../src/yuzu/configuration/configure_ui.cpp" line="24"/>
<source>Full Size (256x256)</source>
- <translation type="unfinished"/>
+ <translation>Volle Größe (256x256)</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.cpp" line="29"/>
@@ -3807,12 +3857,12 @@ Ziehe die Punkte mit deiner Maus, um ihre Position zu ändern. Doppelklicke auf
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="91"/>
<source>Game Icon Size:</source>
- <translation type="unfinished"/>
+ <translation>Spiel-Icon Größe:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="105"/>
<source>Folder Icon Size:</source>
- <translation type="unfinished"/>
+ <translation>Ordner-Icon Größe:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ui.ui" line="119"/>
@@ -3865,7 +3915,7 @@ Ziehe die Punkte mit deiner Maus, um ihre Position zu ändern. Doppelklicke auf
<message>
<location filename="../../src/yuzu/configuration/configure_vibration.ui" line="23"/>
<source>Press any controller button to vibrate the controller.</source>
- <translation type="unfinished"/>
+ <translation>Drücke einen Knopf um den Controller vibrieren zu lassen.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_vibration.ui" line="30"/>
@@ -3959,7 +4009,7 @@ Ziehe die Punkte mit deiner Maus, um ihre Position zu ändern. Doppelklicke auf
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Überprüfen</translation>
</message>
@@ -4046,7 +4096,7 @@ Ziehe die Punkte mit deiner Maus, um ihre Position zu ändern. Doppelklicke auf
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Nicht spezifiziert</translation>
</message>
@@ -4061,17 +4111,36 @@ Ziehe die Punkte mit deiner Maus, um ihre Position zu ändern. Doppelklicke auf
<translation>Token wurde nicht verfiziert. Die Änderungen an deinem Token wurden nicht gespeichert.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Verifizieren...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation>Verifiziert</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
+ <source>Verification failed</source>
+ <comment>Tooltip</comment>
+ <translation>Verifizierung fehlgeschlagen</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
<source>Verification failed</source>
<translation>Verifizierung fehlgeschlagen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Verifizierung fehlgeschlagen. Prüfe ob dein Nutzername und Token richtig eingegeben wurden und ob deine Internetverbindung korrekt funktioniert.</translation>
</message>
@@ -4140,12 +4209,12 @@ Ziehe die Punkte mit deiner Maus, um ihre Position zu ändern. Doppelklicke auf
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
- <translation type="unfinished"/>
+ <translation>Verbinde</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation>Verbinden</translation>
</message>
@@ -4153,487 +4222,487 @@ Ziehe die Punkte mit deiner Maus, um ihre Position zu ändern. Doppelklicke auf
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonyme Daten werden gesammelt,&lt;/a&gt; um yuzu zu verbessern.&lt;br/&gt;&lt;br/&gt;Möchstest du deine Nutzungsdaten mit uns teilen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetrie</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
- <translation type="unfinished"/>
+ <translation>Defekte Vulkan-Installation erkannt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Lade Web-Applet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Deaktiviere die Web Applikation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>Wie viele Shader im Moment kompiliert werden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Derzeitige Emulations-Geschwindigkeit. Werte höher oder niedriger als 100% zeigen, dass die Emulation scheller oder langsamer läuft als auf einer Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Wie viele Bilder pro Sekunde angezeigt werden variiert von Spiel zu Spiel und von Szene zu Szene. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Zeit, die gebraucht wurde, um einen Switch-Frame zu emulieren, ohne Framelimit oder V-Sync. Für eine Emulation bei voller Geschwindigkeit sollte dieser Wert bei höchstens 16.67ms liegen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Zuletzt geladene Dateien leeren</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>&amp;Fortsetzen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Pause</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>yuzu betreibt ein Speil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Warnung veraltetes Spielformat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Du nutzt eine entpackte ROM-Ordnerstruktur für dieses Spiel, welches ein veraltetes Format ist und von anderen Formaten wie NCA, NAX, XCI oder NSP überholt wurde. Entpackte ROM-Ordner unterstützen keine Icons, Metadaten oder Updates.&lt;br&gt;&lt;br&gt;&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;Unser Wiki&lt;/a&gt; enthält eine Erklärung der verschiedenen Formate, die yuzu unterstützt. Diese Nachricht wird nicht noch einmal angezeigt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>ROM konnte nicht geladen werden!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>ROM-Format wird nicht unterstützt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Beim Initialisieren des Video-Kerns ist ein Fehler aufgetreten.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>ROM konnte nicht geladen werden! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Bitte folge der &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu-Schnellstart-Anleitung&lt;/a&gt; um deine Dateien zu extrahieren.&lt;br&gt;Hilfe findest du im yuzu-Wiki&lt;/a&gt; oder dem yuzu-Discord&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Ein unbekannter Fehler ist aufgetreten. Bitte prüfe die Log-Dateien auf mögliche Fehlermeldungen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-Bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-Bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Speicherdaten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Mod-Daten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Konnte Verzeichnis %1 nicht öffnen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Verzeichnis existiert nicht!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Fehler beim Öffnen des transferierbaren Shader-Caches</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Inhalte</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Update</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Eintrag entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>Installiertes Spiel %1 entfernen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>Erfolgreich entfernt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>Das Spiel wurde entfernt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>Fehler beim Entfernen von %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Das Spiel ist nicht im NAND installiert und kann somit nicht entfernt werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>Das Update wurde entfernt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>Es ist kein Update für diesen Titel installiert.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>Es sind keine DLC für diesen Titel installiert.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>%1 DLC entfernt. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Transferierbaren OpenGL Shader Cache löschen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Transferierbaren Vulkan Shader Cache löschen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Alle transferierbaren Shader Caches löschen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>Spiel-Einstellungen entfernen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Datei entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Fehler beim Entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>Es existiert kein Shader-Cache für diesen Titel.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Der transferierbare Shader-Cache wurde entfernt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Konnte den transferierbaren Shader-Cache nicht entfernen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Fehler beim Entfernen der transferierbaren Shader Caches</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Fehler beim Entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Es existieren keine Spiel-Einstellungen für dieses Spiel.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Die Spiel-Einstellungen wurden entfernt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Die Spiel-Einstellungen konnten nicht entfernt werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS-Extraktion fehlgeschlagen!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Das RomFS konnte wegen eines Fehlers oder Abbruchs nicht kopiert werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Komplett</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Nur Ordnerstruktur</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>RomFS Extraktions-Modus auswählen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Bitte wähle, wie das RomFS gespeichert werden soll.&lt;br&gt;&quot;Full&quot; wird alle Dateien des Spiels extrahieren, während &lt;br&gt;&quot;Skeleton&quot; nur die Ordnerstruktur erstellt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>RomFS wird extrahiert...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Abbrechen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS wurde extrahiert!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>Der Vorgang wurde erfolgreich abgeschlossen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Fehler beim Öffnen von %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Verzeichnis auswählen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Einstellungen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Spiel-Einstellungen konnten nicht geladen werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch-Programme (%1);;Alle Dateien (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Datei laden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Öffne das extrahierte ROM-Verzeichnis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Ungültiges Verzeichnis ausgewählt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Das Verzeichnis, das du ausgewählt hast, enthält keine &apos;main&apos;-Datei.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Installierbares Switch-Programm (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submissions Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Dateien installieren</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n Datei verbleibend</numerusform><numerusform>%n Dateien verbleibend</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Datei &quot;%1&quot; wird installiert...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>NAND-Installation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Um Konflikte zu vermeiden, raten wir Nutzern davon ab, Spiele im NAND zu installieren.
Bitte nutze diese Funktion nur zum Installieren von Updates und DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n file was newly installed
@@ -4641,423 +4710,403 @@ Bitte nutze diese Funktion nur zum Installieren von Updates und DLC.</translatio
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Systemanwendung</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Systemarchiv</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Systemanwendungsupdate</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Firmware-Paket (Typ A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Firmware-Paket (Typ B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Spiel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Spiel-Update</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>Spiel-DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Delta-Titel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Wähle den NCA-Installationstyp aus...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Bitte wähle, als was diese NCA installiert werden soll:
(In den meisten Fällen sollte die Standardeinstellung &apos;Spiel&apos; ausreichen.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Installation fehlgeschlagen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Der Titel-Typ, den du für diese NCA ausgewählt hast, ist ungültig.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Datei nicht gefunden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Datei &quot;%1&quot; nicht gefunden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Fehlender yuzu-Account</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Um einen Kompatibilitätsbericht abzuschicken, musst du einen yuzu-Account mit yuzu verbinden.&lt;br&gt;&lt;br/&gt;Um einen yuzu-Account zu verbinden, prüfe die Einstellungen unter Emulation &amp;gt; Konfiguration &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Fehler beim Öffnen der URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>URL &quot;%1&quot; kann nicht geöffnet werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>TAS Aufnahme</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>Datei von Spieler 1 überschreiben?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>Ungültige Konfiguration erkannt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Handheld-Controller können nicht im Dock verwendet werden. Der Pro-Controller wird verwendet.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>Fehler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
- <translation type="unfinished"/>
+ <translation>Das aktuelle Spiel sucht nicht nach Amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
- <translation type="unfinished"/>
+ <translation>Das aktuelle Amiibo wurde entfernt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo-Datei (%1);; Alle Dateien (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Amiibo laden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Fehler beim Öffnen der Amiibo Datei</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Die Amiibo Datei &quot;%1&quot; konnte nicht zum Lesen geöffnet werden.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Fehler beim Lesen der Amiibo-Daten</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Amiibo-Daten können nicht vollständig gelesen werden. Es wurde erwartet, dass %1 Bytes gelesen werden, es konnten aber nur %2 Bytes gelesen werden.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Fehler beim Laden der Amiibo-Daten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Amiibo-Daten konnten nicht geladen werden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Screenshot aufnehmen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>PNG Bild (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS Zustand: Läuft %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>TAS Zustand: Aufnahme %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>TAS Zustand: Ungültig</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Skalierung: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Geschwindigkeit: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Geschwindigkeit: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Spiel: %1 FPS (Unbegrenzt)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Spiel: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Frame: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU HOCH</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU EXTREM</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>GPU FEHLER</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
- <translation type="unfinished"/>
+ <translation>DOCKED</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
- <translation type="unfinished"/>
+ <translation>HANDHELD</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>NÄCHSTER</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>BILINEAR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>BIKUBISCH</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
- <translation type="unfinished"/>
+ <translation>GAUSSIAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>Das Spiel, dass du versuchst zu spielen, benötigt bestimmte Dateien von deiner Switch-Konsole.&lt;br/&gt;&lt;br/&gt;Um Informationen darüber zu erhalten, wie du diese Dateien von deiner Switch extrahieren kannst, prüfe bitte die folgenden Wiki-Seiten: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;System-Archive und Shared Fonts von einer Switch-Konsole extrahieren&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Willst du zur Spiele-Liste zurückkehren und die Emulation beenden? Das Fortsetzen der Emulation könnte zu Spielfehlern, Abstürzen, beschädigten Speicherdaten und anderen Fehlern führen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>yuzu konnte ein Switch Systemarchiv nicht finden. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>yuzu konnte ein Switch Systemarchiv nicht finden: %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Systemarchiv nicht gefunden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Systemarchiv fehlt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu konnte die Switch Shared Fonts nicht finden. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Shared Fonts nicht gefunden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Shared Font fehlt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Schwerwiegender Fehler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>Ein schwerwiegender Fehler ist aufgetreten, bitte prüfe die Log-Dateien auf mögliche Fehlermeldungen. Weitere Informationen: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Wie kann ich eine Log-Datei hochladen&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Willst du zur Spiele-Liste zurückkehren und die Emulation beenden? Das Fortsetzen der Emulation könnte zu Spielfehlern, Abstürzen, beschädigten Speicherdaten und anderen Fehlern führen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Fataler Fehler aufgetreten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Schlüsselableitung bestätigen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5070,37 +5119,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
Dieser Prozess wird die generierten Schlüsseldateien löschen und die Schlüsselableitung neu starten.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>Fuses fehlen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation> - BOOT0 fehlt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - BCPKG2-1-Normal-Main fehlt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation> - PRODINFO fehlt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>Derivationskomponenten fehlen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5108,39 +5157,39 @@ on your system&apos;s performance.</source>
Dies könnte, je nach Leistung deines Systems, bis zu einer Minute dauern.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Schlüsselableitung</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>RomFS wählen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Wähle, welches RomFS du speichern möchtest.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Bist du sicher, dass du yuzu beenden willst?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Bist du sicher, dass du die Emulation stoppen willst? Jeder nicht gespeicherte Fortschritt geht verloren.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5463,7 +5512,7 @@ Screen.</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="51"/>
<source>Preferred Game</source>
- <translation type="unfinished"/>
+ <translation>Bevorzugtes Spiel</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="61"/>
@@ -5478,7 +5527,7 @@ Screen.</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="101"/>
<source>(Leave blank for open game)</source>
- <translation type="unfinished"/>
+ <translation>(Leer lassen für offenes Spiel)</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="118"/>
@@ -5498,7 +5547,7 @@ Screen.</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="153"/>
<source>Load Previous Ban List</source>
- <translation type="unfinished"/>
+ <translation>Vorherige Bann-Liste laden</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="184"/>
@@ -5519,12 +5568,12 @@ Screen.</source>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>Fehler</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5533,11 +5582,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5559,112 +5609,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation>Hauptfenster</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Screenshot aufnehmen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
- <translation type="unfinished"/>
+ <translation>GPU-Genauigkeit ändern</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
- <translation type="unfinished"/>
+ <translation>Emulation fortsetzen/pausieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation>Vollbild verlassen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation>yuzu verlassen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Vollbild</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Datei laden</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
- <translation type="unfinished"/>
+ <translation>Amiibo laden/entfernen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
- <translation type="unfinished"/>
+ <translation>Emulation neustarten</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
- <translation type="unfinished"/>
+ <translation>Emulation stoppen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
- <translation type="unfinished"/>
+ <translation>TAS aufnehmen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
- <translation type="unfinished"/>
+ <translation>TAS neustarten</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
- <translation type="unfinished"/>
+ <translation>TAS starten/stoppen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5744,7 +5793,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="14"/>
<source>Public Room Browser</source>
- <translation type="unfinished"/>
+ <translation>Browser für öffentliche Räume</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="32"/>
@@ -5775,45 +5824,45 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="103"/>
<source>Refresh Lobby</source>
- <translation type="unfinished"/>
+ <translation>Lobby aktualisieren</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation>Passwort zum Joinen benötigt</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation>Passwort:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation>Raumname</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
- <translation type="unfinished"/>
+ <translation>Bevorzugtes Spiel</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation>Host</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Spieler</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
- <translation type="unfinished"/>
+ <translation>Aktualisiere</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation>Liste aktualisieren</translation>
</message>
@@ -5973,7 +6022,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/main.ui" line="254"/>
<source>Browse Public Game Lobby</source>
- <translation type="unfinished"/>
+ <translation>Öffentliche Spiele-Lobbys durchsuchen</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="262"/>
@@ -5988,12 +6037,12 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/main.ui" line="275"/>
<source>Direct Connect to Room</source>
- <translation type="unfinished"/>
+ <translation>Direkte Verbindung zum Raum</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="283"/>
<source>Show Current Room</source>
- <translation type="unfinished"/>
+ <translation>Aktuellen Raum anzeigen</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="291"/>
@@ -6090,7 +6139,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="41"/>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="73"/>
<source>Refreshing</source>
- <translation type="unfinished"/>
+ <translation>Aktualisiere</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="51"/>
@@ -6100,7 +6149,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="40"/>
<source>Subject</source>
- <translation type="unfinished"/>
+ <translation>Thema</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="41"/>
@@ -6110,7 +6159,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="83"/>
<source>Forum Username</source>
- <translation type="unfinished"/>
+ <translation>Forum Benutzername</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="88"/>
@@ -6135,12 +6184,12 @@ Debug Message: </source>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="48"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="94"/>
<source>Not Connected. Click here to find a room!</source>
- <translation type="unfinished"/>
+ <translation>Nicht verbunden! Hier klicken um Raum zu finden!</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Verbunden</translation>
</message>
@@ -6162,7 +6211,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation>Neue Nachrichten erhalten</translation>
</message>
@@ -6172,17 +6221,17 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="11"/>
<source>Username is not valid. Must be 4 to 20 alphanumeric characters.</source>
- <translation type="unfinished"/>
+ <translation>Benutzername ist ungültig. Muss aus 4 bis 20 alphanumerischen Zeichen bestehen.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="13"/>
<source>Room name is not valid. Must be 4 to 20 alphanumeric characters.</source>
- <translation type="unfinished"/>
+ <translation>Raumname ist ungütig. Muss aus 4 bis 20 alphanumerischen Zeichen bestehen.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="15"/>
<source>Username is already in use or not valid. Please choose another.</source>
- <translation type="unfinished"/>
+ <translation>Benutzername wird bereits genutzt oder ist ungültig. Bitte wähle einen anderen.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="17"/>
@@ -6247,12 +6296,12 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="45"/>
<source>You have been kicked by the room host.</source>
- <translation type="unfinished"/>
+ <translation>Sie wurden vom Raum-Ersteller gekickt.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="47"/>
<source>IP address is already in use. Please choose another.</source>
- <translation type="unfinished"/>
+ <translation>IP-Addresse wird bereits genutzt. Bitte wählen Sie eine andere aus.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="49"/>
@@ -6266,22 +6315,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation>Spiel läuft bereits</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation>Raum verlassen</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation>Verbindung trennen</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6289,7 +6355,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>Fehler</translation>
</message>
@@ -6348,7 +6414,7 @@ p, li { white-space: pre-wrap; }
<translation>%1 spielt %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation>Spielt kein Spiel</translation>
</message>
@@ -6403,7 +6469,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[nicht gesetzt]</translation>
</message>
@@ -6418,10 +6484,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Achse %1%2</translation>
</message>
@@ -6435,9 +6501,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[unbekannt]</translation>
</message>
@@ -6593,7 +6659,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="118"/>
<source>[undefined]</source>
- <translation type="unfinished"/>
+ <translation>[undefiniert]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="328"/>
@@ -6602,15 +6668,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[ungültig]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation type="unfinished"/>
</message>
@@ -6618,35 +6684,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation>%1%2Achse %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation>%1%2Achse %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2Bewegung %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2Knopf %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[unbenutzt]</translation>
</message>
@@ -6687,7 +6753,7 @@ p, li { white-space: pre-wrap; }
<translation>Extra</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/languages/el.ts b/dist/languages/el.ts
index 6369a8f0e..b24943792 100644
--- a/dist/languages/el.ts
+++ b/dist/languages/el.ts
@@ -89,78 +89,78 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -755,200 +755,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Θύρα:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Καταγραφή Συμβάντων</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Παγκόσμιο φίλτρο αρχείου καταγραφής</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Άνοιγμα θέσης του αρχείου καταγραφής</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Όταν επιλεγεί, το μέγιστο μέγεθος του αρχείου καταγραφής αυξάνεται από 100 MB σε 1 GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Ενεργοποίηση Εκτεταμένης Καταγραφής**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Σπιτικό</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Γραφικά</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Όταν είναι επιλεγμένο, το API γραφικών εισέρχεται σε μια πιο αργή λειτουργία εντοπισμού σφαλμάτων</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Ενεργοποίηση του Εντοπισμού Σφαλμάτων Γραφικών</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>Όταν είναι επιλεγμένο, ενεργοποιεί την ένδειξη σφαλμάτων Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Ενεργοποίηση του Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation>Όταν επιλεγεί, θα απορρίψει όλους τους αρχικούς assembler shaders από την κρυφή μνήμη ή το παιχνίδι σκίασης δίσκου όπως βρέθηκε</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>Όταν είναι επιλεγμένο, απενεργοποιεί τη μακροεντολή Just In Time compiler. Η ενεργοποίηση αυτού κάνει τα παιχνίδια να τρέχουν πιο αργά</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Απενεργοποίηση του Macro JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>Ενεργοποίηση Shader Feedback</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>Όταν είναι επιλεγμένο, εκτελεί shaders χωρίς αλλαγές στη λογική του βρόχου</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>Απενεργοποίηση των ελέγχων ασφαλείας βρόχου</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Εντοπισμός Σφαλμάτων</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
- <source>Enable FS Access Log</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Προχωρημένα</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Ενεργοποίηση Εντοπισμού Σφαλμάτων CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Ενεργοποίηση Βεβαιώσεων Εντοπισμού Σφαλμάτων</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>Ενεργοποίηση Auto-Stub**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Αυτό θα μηδενιστεί αυτόματα όταν το yuzu κλείσει.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1567,37 +1602,47 @@ This would ban both their forum username and their IP address.</source>
<translation>Χρήση Γοργού Ρυθμού GPU (Τέχνασμα)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Ανισοτροπικό Φιλτράρισμα:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>Αυτόματα</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Προεπιλεγμένο</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2089,7 +2134,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Αριστερό Stick</translation>
</message>
@@ -2183,14 +2228,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2209,7 +2254,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Συν</translation>
</message>
@@ -2222,15 +2267,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2287,231 +2332,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Δεξιός Μοχλός</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Καθαρισμός</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[άδειο]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Κουμπί εναλλαγής</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>Κουμπί αντιστροφής</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Κουμπί εναλλαγής</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Αντιστροφή άξονα</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>Ορισμός ορίου</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Επιλέξτε μια τιμή μεταξύ 0% και 100%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation>Ρύθμιση κατωφλίου γυροσκοπίου</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Χαρτογράφηση Αναλογικού Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Αφού πατήσετε OK, μετακινήστε πρώτα το joystick σας οριζόντια και μετά κατακόρυφα.
Για να αντιστρέψετε τους άξονες, μετακινήστε πρώτα το joystick κατακόρυφα και μετά οριζόντια.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation>Κεντρικός άξονας</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Νεκρή Ζώνη: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Εύρος Τροποποιητή: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Διπλά Joycons</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Αριστερό Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Δεξί Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Handheld</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>Χειριστήριο GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>Χειριστήριο NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>Χειριστήριο SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>Χειριστήριο N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[αναμονή]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Νέο Προφίλ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Εισαγάγετε ένα όνομα προφίλ:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Δημιουργία Προφίλ Χειρισμού</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>Το όνομα του προφίλ δεν είναι έγκυρο!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Η δημιουργία του προφίλ χειρισμού &quot;%1&quot; απέτυχε</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Διαγραφή Προφίλ Χειρισμού</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Η διαγραφή του προφίλ χειρισμού &quot;%1&quot; απέτυχε</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Φόρτωση Προφίλ Χειρισμού</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Η φόρτωση του προφίλ χειρισμού &quot;%1&quot; απέτυχε</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Αποθήκευση Προφίλ Χειρισμού</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Η αποθήκευση του προφίλ χειρισμού &quot;%1&quot; απέτυχε</translation>
</message>
@@ -2766,42 +2816,42 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation>Προγραμματιστής</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Πρόσθετα</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Γενικά</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Σύστημα</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Γραφικά</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Προχ. Γραφικά</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Ήχος</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Ιδιότητες</translation>
</message>
@@ -3447,7 +3497,7 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<message>
<location filename="../../src/yuzu/configuration/configure_system.ui" line="431"/>
<source>RNG Seed</source>
- <translation type="unfinished"/>
+ <translation>RNG Seed</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_system.ui" line="439"/>
@@ -3513,47 +3563,47 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Αυτό είναι ένα πειραματικό χαρακτηριστικό.&lt;br/&gt;Δεν θα αναπαράγει τέλεια καρέ με την τρέχουσα, ατελή μέθοδο συγχρονισμού.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Ρυθμίσεις</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>Ενεργοποίηση λειτουργιών TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>Σενάριο επανάληψης</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>Παύση εκτέλεσης κατά τη διάρκεια φόρτωσης</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>Κατάλογος Σεναρίων</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Μονοπάτι</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3962,7 +4012,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Επαλήθευση</translation>
</message>
@@ -3974,7 +4024,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="66"/>
<source>Token: </source>
- <translation type="unfinished"/>
+ <translation>Διαπιστευτήριο:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="76"/>
@@ -3984,7 +4034,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="93"/>
<source>What is my token?</source>
- <translation type="unfinished"/>
+ <translation>Ποιο είναι το διακριτικό μου;</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="118"/>
@@ -4009,7 +4059,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="150"/>
<source>Telemetry ID:</source>
- <translation type="unfinished"/>
+ <translation>Αναγνωριστικό τηλεμετρίας:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="166"/>
@@ -4029,7 +4079,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="68"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Μάθετε περισσότερα&lt;/span&gt;&lt;/a&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="72"/>
@@ -4049,7 +4099,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation type="unfinished"/>
</message>
@@ -4064,17 +4114,36 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
+ <source>Verification failed</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
<source>Verification failed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation type="unfinished"/>
</message>
@@ -4143,12 +4212,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation type="unfinished"/>
</message>
@@ -4156,907 +4225,892 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Τηλεμετρία</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
- <translation type="unfinished"/>
+ <translation>Πόσα καρέ ανά δευτερόλεπτο εμφανίζει το παιχνίδι αυτή τη στιγμή. Αυτό διαφέρει από παιχνίδι σε παιχνίδι και από σκηνή σε σκηνή.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>&amp;Συνέχεια</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Παύση</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
- <translation type="unfinished"/>
+ <translation>Μη μεταφρασμένη συμβολοσειρά
+
+Χρησιμοποιείτε τη μορφή καταλόγου αποδομημένης ROM για αυτό το παιχνίδι, η οποία είναι μια ξεπερασμένη μορφή που έχει αντικατασταθεί από άλλες, όπως NCA, NAX, XCI ή NSP. Οι αποδομημένοι κατάλογοι ROM στερούνται εικονιδίων, μεταδεδομένων και υποστήριξης ενημερώσεων.&lt;br&gt;&lt;br&gt;
+Για μια εξήγηση των διαφόρων μορφών Switch που υποστηρίζει το yuzu,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt; δείτε το wiki μας &lt;/a&gt;. Αυτό το μήνυμα δεν θα εμφανιστεί ξανά.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
- <translation type="unfinished"/>
+ <translation>Σφάλμα κατά τη φόρτωση της ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
- <translation type="unfinished"/>
+ <translation>Εμφανίστηκε ένα απροσδιόριστο σφάλμα. Ανατρέξτε στο αρχείο καταγραφής για περισσότερες λεπτομέρειες.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Αποθήκευση δεδομένων</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Ο φάκελος δεν υπάρχει!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Περιεχόμενα</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Ενημέρωση</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Αφαίρεση Αρχείου</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
- <translation type="unfinished"/>
+ <translation>Επιλογή λειτουργίας απόρριψης RomFS </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
- <translation type="unfinished"/>
+ <translation>Μη αποθηκευμένη μετάφραση.
+Παρακαλούμε επιλέξτε τον τρόπο με τον οποίο θα θέλατε να γίνει η απόρριψη της RomFS.&lt;br&gt;
+Η επιλογή Πλήρης θα αντιγράψει όλα τα αρχεία στο νέο κατάλογο, ενώ η επιλογή &lt;br&gt; Σκελετός θα δημιουργήσει μόνο τη δομή του καταλόγου.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Ακύρωση</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>Η επέμβαση ολοκληρώθηκε με επιτυχία.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Επιλογή καταλόγου</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Ιδιότητες</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Φόρτωση αρχείου</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Αποτελέσματα εγκατάστασης</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Εφαρμογή συστήματος</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Παιχνίδι</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Ενημέρωση παιχνιδιού</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>DLC παιχνιδιού</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
- <translation type="unfinished"/>
+ <translation>Επιλέξτε τον τύπο εγκατάστασης NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Το αρχείο δεν βρέθηκε</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Το αρχείο &quot;%1&quot; δεν βρέθηκε</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Σφάλμα κατα το άνοιγμα του URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Αδυναμία ανοίγματος του URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Φόρτωση Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
- <translation type="unfinished"/>
+ <translation>Σφάλμα φόρτωσης δεδομένων Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Αδυναμία φόρτωσης Amiibo δεδομένων.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
- <translation type="unfinished"/>
+ <translation>Λήψη στιγμιότυπου οθόνης</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>Εικόνα PBG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Έναρξη</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Κλίμακα: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Ταχύτητα: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Ταχύτητα: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
- <translation type="unfinished"/>
+ <translation>Καρέ: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Σοβαρό Σφάλμα</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Παρουσιάστηκε Σοβαρό Σφάλμα</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5067,76 +5121,76 @@ This will delete your autogenerated key files and re-run the key derivation modu
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation>- Λείπει το BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- Λείπει το BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation>- Λείπει το PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Είστε σίγουροι ότι θέλετε να κλείσετε το yuzu;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5380,7 +5434,7 @@ workarounds.</source>
<location filename="../../src/yuzu/game_list_p.h" line="152"/>
<source>Game functions, but with major graphical or audio glitches. Unable to progress in specific areas due to glitches
even with workarounds.</source>
- <translation type="unfinished"/>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Το παιχνίδι λειτουργεί, αλλά με σημαντικά γραφικά ή ακουστικά σφάλματα. Αδύνατο να προχωρήσει σε συγκεκριμένες περιοχές λόγω σφαλμάτων ακόμα και με μικροδιορθώσεις.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/game_list_p.h" line="153"/>
@@ -5512,12 +5566,12 @@ Screen.</source>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5526,11 +5580,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5552,112 +5607,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
- <translation type="unfinished"/>
+ <translation>Λήψη στιγμιότυπου οθόνης</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Πλήρη Οθόνη</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Φόρτωση αρχείου</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5771,42 +5825,42 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation type="unfinished"/>
</message>
@@ -6133,7 +6187,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Συνδεδεμένο</translation>
</message>
@@ -6155,7 +6209,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation type="unfinished"/>
</message>
@@ -6259,22 +6313,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6282,7 +6353,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
@@ -6337,7 +6408,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation type="unfinished"/>
</message>
@@ -6392,7 +6463,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[μη ορισμένο]</translation>
</message>
@@ -6407,12 +6478,12 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
- <translation type="unfinished"/>
+ <translation>Άξονας%1%2</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="60"/>
@@ -6424,9 +6495,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[άγνωστο]</translation>
</message>
@@ -6591,15 +6662,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation type="unfinished"/>
</message>
@@ -6607,35 +6678,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[άδειο]</translation>
</message>
@@ -6676,7 +6747,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
@@ -7042,7 +7113,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="147"/>
<source>Call stack</source>
- <translation type="unfinished"/>
+ <translation>Κλήση stack</translation>
</message>
</context>
<context>
@@ -7068,7 +7139,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="228"/>
<source>waiting for all objects</source>
- <translation type="unfinished"/>
+ <translation>αναμονή για όλα τα αντικείμενα</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="229"/>
@@ -7114,7 +7185,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="264"/>
<source>waiting for objects</source>
- <translation type="unfinished"/>
+ <translation>αναμονή αντικειμένων</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="267"/>
@@ -7189,7 +7260,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="355"/>
<source>priority = %1(current) / %2(normal)</source>
- <translation type="unfinished"/>
+ <translation>προτεραιότητα = %1(τρέχον) / %2(κανονικό)</translation>
</message>
<message>
<location filename="../../src/yuzu/debugger/wait_tree.cpp" line="359"/>
diff --git a/dist/languages/es.ts b/dist/languages/es.ts
index 3b81336eb..e84442fdc 100644
--- a/dist/languages/es.ts
+++ b/dist/languages/es.ts
@@ -95,82 +95,82 @@ p, li { white-space: pre-wrap; }
<translation>Enviar mensaje</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation>Miembros</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation>%1 se ha unido</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation>%1 se ha ido</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation>%1 ha sido expulsado</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
- <translation>%1 ha sido baneado</translation>
+ <translation>%1 ha sido vetado</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
- <translation>%1 ha sido desbaneado</translation>
+ <translation>%1 se le ha retirado el veto</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation>Ver perfil</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation>Bloquear jugador</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation>Cuando bloqueas a un jugador, ya no recibirás mensajes de ellos. &lt;br&gt;&lt;br&gt; ¿Estás seguro de que quieres bloquear a %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation>Expulsar</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
- <translation>Banear</translation>
+ <translation>Vetar</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation>Expulsar jugador</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation>¿Estás seguro de que quieres &lt;b&gt;expulsar&lt;/b&gt; a %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
- <translation>Banear jugador</translation>
+ <translation>Vetar jugador</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
- <translation>¿Estas seguro de que quieres &lt;b&gt;expulsar y banear a&lt;/b&gt;%1?
+ <translation>¿Estas seguro de que quieres &lt;b&gt;expulsar y vetar a&lt;/b&gt;%1?
Esto banearía su nombre del foro y su dirección IP.</translation>
</message>
@@ -771,200 +771,235 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation>Depurador</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Activar GDB Stub</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Puerto:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Registro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Filtro del registro global</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Ver registro en consola</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Abrir ubicación del archivo de registro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Cuando se marque, el tamaño maximo del registro aumenta de 100 MB a 1 GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Habilitar registro extendido**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Cadena de argumentos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Gráficos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Cuando esté marcado, la API gráfica entrará en un modo de depuración más lento.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Activar depuración de gráficos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>Cuando esté marcado, activará los volcados de los fallos Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Activar Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation>Al activarlo, esto volcará todos los sombreadores originales del ensamblador de la caché de sombreadores en disco o del juego encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation>Volcar sombreadores del juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation>Cuando esté activado, se volcarán todos los programas macro de la GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation>Volcar Macros Maxwell</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>Cuando esté marcado, se desactiva el compilador de macro Just In Time. Activar esto hace que los juegos se ejecuten más lento.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Desactivar macro JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>Cuando esté marcado, yuzu hará un registro de las estadísticas del caché de tubería compilado </translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>Activar información de shaders</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>Cuando esté marcado, se ejecutarán los shaders sin cambios de bucles lógicos.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>Desactivar comprobaciones de seguridad de bucles</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Depuración</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
- <source>Enable FS Access Log</source>
- <translation>Activar registro de acceso FS</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>Activar servicios de reporte detallados**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
- <translation>Volcar comandos de audio a la consola**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
+ <translation>Activar registro de acceso FS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Activa esta opción para mostrar en la consola la última lista de comandos de audio generada. Solo afecta a los juegos que utilizan el renderizador de audio.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>Activar servicios de reporte detallados**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
+ <translation>Volcar comandos de audio a la consola**</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Avanzado</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Modo quiosco (Quest)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Activar depuración de la CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Activar alertas de depuración</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>Activar Auto-Stub**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation>Habilitar todo tipo de controles</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Desactivar Web applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Esto se reiniciará automáticamente cuando yuzu se cierre.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1583,37 +1618,47 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
<translation>Usar tiempo rápido en la GPU (Hack)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Filtrado anisotrópico:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>Automático</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Valor predeterminado</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>x2</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>x4</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>x8</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>x16</translation>
</message>
@@ -2105,7 +2150,7 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Palanca izquierda</translation>
</message>
@@ -2199,14 +2244,14 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2225,7 +2270,7 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Más</translation>
</message>
@@ -2238,15 +2283,15 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2303,231 +2348,236 @@ Esto banearía su nombre del foro y su dirección IP.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Palanca derecha</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Borrar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[no definido]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Alternar botón</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>Invertir botón</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Alternar botón</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Invertir ejes</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>Configurar umbral</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Seleccione un valor entre 0% y 100%.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation>Configurar umbral del Giroscopio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Configuración de palanca analógico</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Después de pulsar OK, mueve primero el joystick de manera horizontal, y luego verticalmente.
Para invertir los ejes, mueve primero el joystick de manera vertical, y luego horizontalmente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation>Centrar ejes</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Punto muerto: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Rango del modificador: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Controlador Pro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Joycons duales</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Joycon izquierdo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Joycon derecho</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Portátil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>Controlador de GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>Controlador NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>Controlador SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>Controlador N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Inicio / Pausa</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Palanca de control</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>¡Agita!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[esperando]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Nuevo perfil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Introduce un nombre de perfil:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Crear perfil de entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>¡El nombre de perfil introducido no es válido!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Error al crear el perfil de entrada &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Eliminar perfil de entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Error al eliminar el perfil de entrada &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Cargar perfil de entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Error al cargar el perfil de entrada &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Guardar perfil de entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Error al guardar el perfil de entrada &quot;%1&quot;</translation>
</message>
@@ -2782,42 +2832,42 @@ Para invertir los ejes, mueve primero el joystick de manera vertical, y luego ho
<translation>Desarrollador</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Extras / Add-Ons</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>General</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Gráficos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Gráficos avanz.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Audio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Propiedades</translation>
</message>
@@ -3529,47 +3579,47 @@ Para invertir los ejes, mueve primero el joystick de manera vertical, y luego ho
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Lee la entrada de los controles de los scripts en el mismo formato que los scripts TAS-nx.&lt;br/&gt;Para una mejor explicación, consulta la&lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;página de ayuda&lt;/span&gt;&lt;/a&gt; en la página web de yuzu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>Para comprobar qué teclas de acceso rápido controlan la reproducción/grabación, por favor, revisa la configuración de las Teclas de acceso rápido (Configuración -&gt; General -&gt; Teclas de acceso rápido)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>AVISO: Esto es una característica experimental.&lt;br/&gt;No se reproducirán los scripts perfectamente con el método actual e imperfecto de sincronización.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Ajustes</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>Activar características TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>Repetir script en bucle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>Pausar ejecución durante las cargas</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>Directorio de scripts</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Ruta</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3979,7 +4029,7 @@ Arrastra los puntos para cambiar de posición, o haz doble clic en las celdas de
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Verificar</translation>
</message>
@@ -4066,7 +4116,7 @@ Arrastra los puntos para cambiar de posición, o haz doble clic en las celdas de
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Sin especificar</translation>
</message>
@@ -4081,17 +4131,36 @@ Arrastra los puntos para cambiar de posición, o haz doble clic en las celdas de
<translation>El token no se puede verificar. Los cambios realizados en tu token no se ha guardado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Verificando...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Error de verificación</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Error de verificación</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Error de verificación. Comprueba que has introducido el token correctamente, y que esté funcionando correctamente tu conexión a internet.</translation>
</message>
@@ -4160,12 +4229,12 @@ Arrastra los puntos para cambiar de posición, o haz doble clic en las celdas de
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation>Conectando</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation>Conectar</translation>
</message>
@@ -4173,488 +4242,488 @@ Arrastra los puntos para cambiar de posición, o haz doble clic en las celdas de
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Los datos de uso anónimos se recogen&lt;/a&gt; para ayudar a mejorar yuzu. &lt;br/&gt;&lt;br/&gt;¿Deseas compartir tus datos de uso con nosotros?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetría </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Se ha detectado una instalación corrupta de Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>La inicialización de Vulkan ha fallado durante la ejecución. Haz clic &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;aquí para más información sobre como arreglar el problema&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Cargando Web applet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Desactivar Web applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Deshabilitar el Applet Web puede causar comportamientos imprevistos y debería solo ser usado con Super Mario 3D All-Stars. ¿Estas seguro que quieres deshabilitar el Applet Web?
(Puede ser reactivado en las configuraciones de Depuración.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>La cantidad de shaders que se están construyendo actualmente</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>El multiplicador de escala de resolución seleccionado actualmente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>La velocidad de emulación actual. Los valores superiores o inferiores al 100% indican que la emulación se está ejecutando más rápido o más lento que en una Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>La cantidad de fotogramas por segundo que se está mostrando el juego actualmente. Esto variará de un juego a otro y de una escena a otra.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tiempo que lleva emular un fotograma de la Switch, sin tener en cuenta la limitación de fotogramas o sincronización vertical. Para una emulación óptima, este valor debería ser como máximo de 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Eliminar archivos recientes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>&amp;Continuar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Pausar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>yuzu está ejecutando un juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Advertencia: formato del juego obsoleto</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Está utilizando el formato de directorio de ROM deconstruido para este juego, que es un formato desactualizado que ha sido reemplazado por otros, como los NCA, NAX, XCI o NSP. Los directorios de ROM deconstruidos carecen de íconos, metadatos y soporte de actualizaciones.&lt;br&gt;&lt;br&gt;Para ver una explicación de los diversos formatos de Switch que soporta yuzu,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;echa un vistazo a nuestra wiki&lt;/a&gt;. Este mensaje no se volverá a mostrar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>¡Error al cargar la ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>El formato de la ROM no es compatible.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Se ha producido un error al inicializar el núcleo de video.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu ha encontrado un error al ejecutar el núcleo de video. Esto suele ocurrir al no tener los controladores de la GPU actualizados, incluyendo los integrados. Por favor, revisa el registro para más detalles. Para más información sobre cómo acceder al registro, por favor, consulta la siguiente página: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Como cargar el archivo de registro&lt;/a&gt;. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>¡Error al cargar la ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Por favor, sigue &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;la guía de inicio rápido de yuzu&lt;/a&gt; para revolcar los archivos.&lt;br&gt;Puedes consultar la wiki de yuzu&lt;/a&gt; o el Discord de yuzu&lt;/a&gt; para obtener ayuda.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Error desconocido. Por favor, consulte el archivo de registro para ver más detalles.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Datos de guardado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Datos de mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Error al abrir la carpeta %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>¡La carpeta no existe!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Error al abrir el caché transferible de shaders</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>No se pudo crear el directorio de la caché de los shaders para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Contenidos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Actualización</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Eliminar entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>¿Eliminar el juego instalado %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>Se ha eliminado con éxito</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>Se ha eliminado con éxito el juego base instalado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>Error al eliminar %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>El juego base no está instalado en el NAND y no se puede eliminar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>Se ha eliminado con éxito la actualización instalada.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>No hay ninguna actualización instalada para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>No hay ningún DLC instalado para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Se ha eliminado con éxito %1 DLC instalado(s).</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>¿Deseas eliminar el caché transferible de shaders de OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>¿Deseas eliminar el caché transferible de shaders de Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>¿Deseas eliminar todo el caché transferible de shaders?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>¿Deseas eliminar la configuración personalizada del juego?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Eliminar archivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Error al eliminar la caché de shaders transferibles</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>No existe caché de shaders para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>El caché de shaders transferibles se ha eliminado con éxito.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>No se ha podido eliminar la caché de shaders transferibles.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Error al eliminar las cachés de shaders transferibles</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Cachés de shaders transferibles eliminadas con éxito.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>No se ha podido eliminar el directorio de cachés de shaders transferibles.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Error al eliminar la configuración personalizada del juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>No existe una configuración personalizada para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Se eliminó con éxito la configuración personalizada del juego.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>No se ha podido eliminar la configuración personalizada del juego.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>¡La extracción de RomFS ha fallado!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Se ha producido un error al copiar los archivos RomFS o el usuario ha cancelado la operación.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Completo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Esquema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Elegir método de volcado de RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Seleccione la forma en que quieras volcar el RomFS. &lt;br&gt;Copiará todos los archivos en el nuevo directorio &lt;br&gt; mientras que el esqueleto solo creará la estructura del directorio.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>No hay suficiente espacio en %1 para extraer el RomFS. Por favor, libera espacio o elige otro directorio de volcado en Emulación &gt; Configuración &gt; Sistema &gt; Sistema de archivos &gt; Raíz de volcado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Extrayendo RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Cancelar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>¡La extracción RomFS ha tenido éxito!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>La operación se completó con éxito.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Error al intentar abrir %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Seleccionar directorio</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Propiedades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>No se pueden cargar las propiedades del juego.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Ejecutable de Switch (%1);;Todos los archivos (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Cargar archivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Abrir el directorio de la ROM extraída</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Directorio seleccionado no válido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>El directorio que ha seleccionado no contiene ningún archivo &apos;main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Archivo de Switch Instalable (*.nca *.nsp *.xci);;Archivo de contenidos de Nintendo (*.nca);;Paquete de envío de Nintendo (*.nsp);;Imagen de cartucho NX (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Instalar archivos</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n archivo(s) restantes</numerusform><numerusform>%n archivo(s) restantes</numerusform><numerusform>%n archivo(s) restantes</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Instalando el archivo &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Instalar resultados</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Para evitar posibles conflictos, no recomendamos a los usuarios que instalen juegos base en el NAND.
Por favor, utiliza esta función sólo para instalar actualizaciones y DLCs.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n archivo(s) recién instalado/s
@@ -4663,7 +4732,7 @@ Por favor, utiliza esta función sólo para instalar actualizaciones y DLCs.</tr
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n archivo(s) recién sobreescrito/s
@@ -4672,7 +4741,7 @@ Por favor, utiliza esta función sólo para instalar actualizaciones y DLCs.</tr
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n archivo(s) no se instaló/instalaron
@@ -4681,411 +4750,391 @@ Por favor, utiliza esta función sólo para instalar actualizaciones y DLCs.</tr
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Aplicación del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Archivo del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Actualización de la aplicación del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Paquete de firmware (Tipo A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Paquete de firmware (Tipo B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Actualización de juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>DLC del juego</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Titulo delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Seleccione el tipo de instalación NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Seleccione el tipo de título en el que deseas instalar este NCA como:
(En la mayoría de los casos, el &apos;Juego&apos; predeterminado está bien).</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Fallo en la instalación</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>El tipo de título que seleccionó para el NCA no es válido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Archivo no encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Archivo &quot;%1&quot; no encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>Aceptar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Falta la cuenta de Yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Para enviar un caso de prueba de compatibilidad de juegos, debes vincular tu cuenta de yuzu.&lt;br&gt;&lt;br/&gt; Para vincular tu cuenta de yuzu, ve a Emulación &amp;gt; Configuración &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Error al abrir la URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>No se puede abrir la URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>Grabación TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>¿Sobrescribir archivo del jugador 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>Configuración no válida detectada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>El controlador del modo portátil no puede ser usado en el modo sobremesa. Se seleccionará el controlador Pro en su lugar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation>El juego actual no está buscando amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation>El amiibo actual ha sido eliminado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Archivo amiibo (%1);; Todos los archivos (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Cargar amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Error al abrir el archivo de datos amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>No se puede abrir el archivo amiibo &quot;%1&quot; para leer.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Error al leer el archivo de datos amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>No se puede leer completamente los datos Amiibo. Se esperaban leer %1 bytes, pero solo se puede leer %2 bytes.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Error al cargar los datos Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>No se pueden cargar los datos Amiibo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Captura de pantalla</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>Imagen PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>Estado TAS: ejecutando %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>Estado TAS: grabando %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>Estado TAS: inactivo %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>Estado TAS: nulo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>&amp;Parar de ejecutar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Iniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>Pausar g&amp;rabación</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>G&amp;rabar</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Creando: %n shader(s)</numerusform><numerusform>Construyendo: %n shader(s)</numerusform><numerusform>Construyendo: %n shader(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Escalado: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Velocidad: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Velocidad: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Juego: %1 FPS (desbloqueado)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Juego: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Fotogramas: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU ALTA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU EXTREMA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>GPU ERROR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation>SOBREMESA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation>PORTÁTIL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>PROXIMAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>BILINEAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>BICÚBICO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>GAUSSIANO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>NO AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>El juego que estás intentando cargar requiere archivos adicionales de tu Switch antes de poder jugar. &lt;br/&gt;&lt;br/&gt;Para obtener más información sobre cómo obtener estos archivos, ve a la siguiente página de la wiki: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Volcar archivos del sistema y las fuentes compartidas desde una Consola Switch. &lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;¿Quieres volver a la lista de juegos? Continuar con la emulación puede provocar fallos, datos de guardado corrompidos u otros errores.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>yuzu no pudo localizar el archivo de sistema de la Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>yuzu no pudo localizar un archivo de sistema de la Switch: %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Archivo del sistema no encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Faltan archivos del sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu no pudo encontrar las fuentes compartidas de la Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Fuentes compartidas no encontradas</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Faltan fuentes compartidas</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Error fatal</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu ha encontrado un error fatal, consulta el registro para obtener más detalles. Para obtener más información sobre cómo acceder al registro, consulta la siguiente página: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;¿Cómo cargar el archivo de registro?&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt; Continuar con la emulación puede provocar fallos, datos de guardado corruptos u otros errores.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Error fatal encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Confirmar la clave de rederivación</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5102,37 +5151,37 @@ es lo que quieres hacer si es necesario.
Esto eliminará los archivos de las claves generadas automáticamente y volverá a ejecutar el módulo de derivación de claves.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>Faltan fuses</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation>- Falta BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - Falta BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation> - Falta PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>Faltan componentes de derivación</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Faltan las claves de encriptación. &lt;br&gt;Por favor, sigue &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;la guía rápida de yuzu&lt;/a&gt; para obtener todas tus claves, firmware y juegos.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5141,39 +5190,39 @@ Esto puede llevar unos minutos dependiendo
del rendimiento de su sistema.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Obtención de claves</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Selecciona el destinatario para volcar el RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Por favor, seleccione los RomFS que deseas volcar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>¿Estás seguro de que quieres cerrar yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>¿Estás seguro de que quieres detener la emulación? Cualquier progreso no guardado se perderá.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5549,32 +5598,33 @@ de inicio.</translation>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="197"/>
<source>Host Room</source>
- <translation>Sala del anfitrión</translation>
+ <translation>Crear sala</translation>
</message>
</context>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>Error</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
- <translation>Error al anunciar la sala al lobby público. Para poder publicar una sala en el lobby público, debe tener una cuenta válida de yuzu configurada en Emulación -&gt; Configurar -&gt; Web. Si no quieres publicar una sala en el lobby público, seleccione en su lugar Privada.
+ <translation>Error al anunciar la sala al lobby público. Para poder publicar una sala en el lobby público, debes tener una cuenta válida de yuzu configurada en Emulación -&gt; Configurar -&gt; Web. Si no quieres publicar una sala en el lobby público, seleccione en su lugar Privada.
Mensaje de depuración: </translation>
</message>
</context>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation>Activar/Desactivar audio</translation>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5596,112 +5646,111 @@ Mensaje de depuración: </translation>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation>Ventana principal</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation>Bajar volumen del audio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation>Subir volumen del audio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Captura de pantalla</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation>Cambiar filtro adaptable</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation>Cambiar a modo sobremesa</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation>Cambiar precisión de GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation>Continuar/Pausar emulación</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation>Salir de pantalla completa</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation>Cerrar yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Pantalla completa</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Cargar archivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation>Cargar/Eliminar Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation>Reiniciar emulación</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation>Detener emulación</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation>Grabar TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation>Reiniciar TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation>Iniciar/detener TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation>Alternar barra de filtro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation>Alternar limite de fotogramas</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation>Alternar desplazamiento del ratón</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation>Alternar barra de estado</translation>
</message>
@@ -5816,42 +5865,42 @@ Mensaje de depuración: </translation>
<translation>Actualizar lobby</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation>Contraseña necesaria para unirse</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation>Contraseña:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation>Nombre de la sala</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation>Juego preferente</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation>Anfitrión</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Jugadores</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation>Actualizando</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation>Actualizar lista</translation>
</message>
@@ -6133,7 +6182,7 @@ Mensaje de depuración: </translation>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="51"/>
<source>Unban</source>
- <translation>Desbanear</translation>
+ <translation>Quitar veto</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="40"/>
@@ -6178,7 +6227,7 @@ Mensaje de depuración: </translation>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Conectado</translation>
</message>
@@ -6201,7 +6250,7 @@ Debug Message: </source>
Mensaje de depuración: </translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation>Nuevos mensajes recibidos</translation>
</message>
@@ -6246,42 +6295,42 @@ Mensaje de depuración: </translation>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="26"/>
<source>Unable to connect to the host. Verify that the connection settings are correct. If you still cannot connect, contact the room host and verify that the host is properly configured with the external port forwarded.</source>
- <translation type="unfinished"/>
+ <translation>No se ha podido conectar con el anfitrión. Comprueba que la configuración de la conexión es correcta. Si todavía no puedes conectarte, contacta con el anfitrión de la sala y verifica que el anfitrión tiene configurado correctamente el puerto externo direccionado.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="30"/>
<source>Unable to connect to the room because it is already full.</source>
- <translation type="unfinished"/>
+ <translation>No es posible conectarse a la sala debido a que ya se encuentra llena.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="32"/>
<source>Creating a room failed. Please retry. Restarting yuzu might be necessary.</source>
- <translation type="unfinished"/>
+ <translation>La creación de la sala ha fallado. Por favor reintente. Reiniciar yuzu puede ser necesario.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="34"/>
<source>The host of the room has banned you. Speak with the host to unban you or try a different room.</source>
- <translation type="unfinished"/>
+ <translation>El anfitrión de la sala te ha vetado. Habla con el anfitrión para quitar el veto o prueba con una sala diferente.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="37"/>
<source>Version mismatch! Please update to the latest version of yuzu. If the problem persists, contact the room host and ask them to update the server.</source>
- <translation type="unfinished"/>
+ <translation>¡No coinciden las versiones! Por favor, actualiza a la última versión de yuzu. Si el problema persiste, ponte en contacto con el anfitrión de la sala y pídele que actualice el servidor.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="39"/>
<source>Incorrect password.</source>
- <translation type="unfinished"/>
+ <translation>Contraseña incorrecta</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="40"/>
<source>An unknown error occurred. If this error continues to occur, please open an issue</source>
- <translation type="unfinished"/>
+ <translation>Ha ocurrido un error desconocido. Si el error persiste, por favor, abre una solicitud de errores.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="43"/>
<source>Connection to room lost. Try to reconnect.</source>
- <translation type="unfinished"/>
+ <translation>Conexión a la sala perdida. Intente reconectarse.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="45"/>
@@ -6291,44 +6340,62 @@ Mensaje de depuración: </translation>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="47"/>
<source>IP address is already in use. Please choose another.</source>
- <translation type="unfinished"/>
+ <translation>La dirección IP ya se encuentra en uso. Por favor escoja otra.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="49"/>
<source>You do not have enough permission to perform this action.</source>
- <translation type="unfinished"/>
+ <translation>No tiene permisos suficientes para realizar esta acción.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="50"/>
<source>The user you are trying to kick/ban could not be found.
They may have left the room.</source>
+ <translation>El usuario que estás intentando echar/vetar no se ha podido encontrar.
+Es posible que haya abandonado la sala.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation>Salir de la sala</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
- <translation type="unfinished"/>
+ <translation>Estás por cerrar la sala. Las conexiones de red serán cerradas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
- <translation type="unfinished"/>
+ <translation>Desconectar</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
- <translation type="unfinished"/>
+ <translation>Estás por salir de la sala. Las conexiones de red serán cerradas.</translation>
</message>
</context>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>Error</translation>
</message>
@@ -6379,17 +6446,17 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/multiplayer/lobby_p.h" line="230"/>
<source>%1 is not playing a game</source>
- <translation type="unfinished"/>
+ <translation>%1 no está jugando un juego</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby_p.h" line="232"/>
<source>%1 is playing %2</source>
- <translation type="unfinished"/>
+ <translation>%1 esta jugando %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
- <translation type="unfinished"/>
+ <translation>No está jugando un juego</translation>
</message>
<message>
<location filename="../../src/yuzu/game_list_p.h" line="242"/>
@@ -6442,7 +6509,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[no definido]</translation>
</message>
@@ -6457,10 +6524,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Eje %1%2</translation>
</message>
@@ -6474,9 +6541,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[desconocido]</translation>
</message>
@@ -6641,15 +6708,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[inválido]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation>%1%2Rotación %3</translation>
</message>
@@ -6657,35 +6724,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation>%1%2Eje %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation>%1%2Eje %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2Movimiento %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2Botón %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[no usado]</translation>
</message>
@@ -6726,7 +6793,7 @@ p, li { white-space: pre-wrap; }
<translation>Extra</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/languages/fr.ts b/dist/languages/fr.ts
index d876accfe..35e0292a9 100644
--- a/dist/languages/fr.ts
+++ b/dist/languages/fr.ts
@@ -25,12 +25,18 @@ p, li { white-space: pre-wrap; }
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:12pt;&quot;&gt;yuzu is an experimental open-source emulator for the Nintendo Switch licensed under GPLv3.0+.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:12pt;&quot;&gt;This software should not be used to play games you have not legally obtained.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Ubuntu&apos;; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:12pt;&quot;&gt;yuzu est un émulateur expérimental open-source pour la Nintendo Switch sous licence GPLv3.0+.&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:&apos;MS Shell Dlg 2&apos;; font-size:8pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:12pt;&quot;&gt;Ce logiciel ne doit pas être utilisé pour jouer à des jeux que vous n&apos;avez pas obtenus légalement.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="130"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Site Web&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Code Source &lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributeurs&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="146"/>
@@ -76,95 +82,97 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="14"/>
<source>Room Window</source>
- <translation type="unfinished"/>
+ <translation>Fenêtre du Salon</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="40"/>
<source>Send Chat Message</source>
- <translation type="unfinished"/>
+ <translation>Envoyer un message de chat</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="47"/>
<source>Send Message</source>
- <translation type="unfinished"/>
+ <translation>Envoyer le message</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation>Membres</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation>%1 a rejoint</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation>%1 a quitté</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
- <translation type="unfinished"/>
+ <translation>%1 a été expulsé</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
- <translation type="unfinished"/>
+ <translation>%1 a été banni</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
- <translation type="unfinished"/>
+ <translation>%1 a été débanni</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
- <translation type="unfinished"/>
+ <translation>Voir le profile</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
- <translation type="unfinished"/>
+ <translation>Bloquer le joueur</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
- <translation type="unfinished"/>
+ <translation>Lorsque vous bloquez un joueur, vous ne recevrez plus de messages de chat de sa part.&lt;br&gt;&lt;br&gt;Êtes-vous sûr de vouloir bloquer %1 ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
- <translation type="unfinished"/>
+ <translation>Expulser</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
- <translation type="unfinished"/>
+ <translation>Bannir</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
- <translation type="unfinished"/>
+ <translation>Expulser le joueur</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
- <translation type="unfinished"/>
+ <translation>Êtes-vous sûr de vouloir &lt;b&gt;expluser&lt;/b&gt; %1 ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
- <translation type="unfinished"/>
+ <translation>Bannir le joueur</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
- <translation type="unfinished"/>
+ <translation>Êtes-vous sûr de vouloir &lt;b&gt;expluser et bannir &lt;/b&gt; %1 ?
+
+Cela bannirait à la fois son nom d&apos;utilisateur du forum et son adresse IP.</translation>
</message>
</context>
<context>
@@ -172,7 +180,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="14"/>
<source>Room Window</source>
- <translation type="unfinished"/>
+ <translation>Fenêtre du Salon</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="27"/>
@@ -182,7 +190,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="47"/>
<source>Moderation...</source>
- <translation type="unfinished"/>
+ <translation>Modération...</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="57"/>
@@ -200,12 +208,12 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="87"/>
<source>Disconnected</source>
- <translation type="unfinished"/>
+ <translation>Déconnecté</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="100"/>
<source>%1 (%2/%3 members) - connected</source>
- <translation type="unfinished"/>
+ <translation>%1 (%2/%3 membres) - connectés</translation>
</message>
</context>
<context>
@@ -334,7 +342,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_audio.ui" line="42"/>
<source>Output Device</source>
- <translation type="unfinished"/>
+ <translation>Périphérique de sortie</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_audio.ui" line="56"/>
@@ -373,37 +381,37 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="14"/>
<source>Configure Infrared Camera</source>
- <translation type="unfinished"/>
+ <translation>Configurer la caméra infrarouge</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="26"/>
<source>Select where the image of the emulated camera comes from. It may be a virtual camera or a real camera.</source>
- <translation type="unfinished"/>
+ <translation>Sélectionnez d&apos;où provient l&apos;image de la caméra émulée. Il peut s&apos;agir d&apos;une caméra virtuelle ou d&apos;une caméra réelle.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="52"/>
<source>Camera Image Source:</source>
- <translation type="unfinished"/>
+ <translation>Source de l&apos;image de la caméra :</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="71"/>
<source>Input device:</source>
- <translation type="unfinished"/>
+ <translation>Périphérique d&apos;entrée :</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="96"/>
<source>Preview</source>
- <translation type="unfinished"/>
+ <translation>Aperçu</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="108"/>
<source>Resolution: 320*240</source>
- <translation type="unfinished"/>
+ <translation>Résolution : 320*240</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="115"/>
<source>Click to preview</source>
- <translation type="unfinished"/>
+ <translation>Cliquez pour prévisualiser</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="140"/>
@@ -726,7 +734,11 @@ Cette option améliore la vitesse en réduisant la précision des instructions f
&lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it causes guest exclusive memory reads/writes to be done directly into memory and make use of Host's MMU.&lt;/div&gt;
&lt;div style=&quot;white-space: nowrap&quot;&gt;Disabling this forces all exclusive memory accesses to use Software MMU Emulation.&lt;/div&gt;
</source>
- <translation type="unfinished"/>
+ <translation>
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Cette optimisation accélère les accès exclusifs à la mémoire par le programme invité.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Son activation entraîne l&apos;exécution directe de lectures/écritures de la mémoire exclusive de l&apos;invité dans la mémoire et l&apos;utilisation du MMU de l&apos;hôte.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;La désactivation de cette option force tous les accès exclusifs à la mémoire à utiliser l&apos;émulation logicielle MMU.&lt;/div&gt;
+ </translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="161"/>
@@ -739,12 +751,15 @@ Cette option améliore la vitesse en réduisant la précision des instructions f
&lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up exclusive memory accesses by the guest program.&lt;/div&gt;
&lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it reduces the overhead of fastmem failure of exclusive memory accesses.&lt;/div&gt;
</source>
- <translation type="unfinished"/>
+ <translation>
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Cette optimisation accélère les accès exclusifs à la mémoire par le programme invité.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;L&apos;activer réduit la surcharge de l&apos;échec fastmem des accès exclusifs à la mémoire.&lt;/div&gt;
+ </translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="174"/>
<source>Enable recompilation of exclusive memory instructions</source>
- <translation type="unfinished"/>
+ <translation>Activer la recompilation des instructions de mémoire exclusives</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="199"/>
@@ -755,200 +770,235 @@ Cette option améliore la vitesse en réduisant la précision des instructions f
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
- <translation type="unfinished"/>
+ <translation>Débogueur</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Activer le &quot;stub&quot; de GDB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Port :</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>S&apos;enregistrer</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Filtre de log global</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Afficher le relevé d&apos;événements dans la console</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Ouvrir l&apos;emplacement du journal de logs</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Lorsque coché, la taille maximum du relevé d&apos;événements augmente de 100 Mo à 1 Go</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Activer la Journalisation Étendue**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Chaîne d&apos;arguments</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Graphismes</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Lorsque coché, l&apos;API graphique entre dans un mode de débogage plus lent</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Activer le débogage des graphismes </translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>Une fois cochée, cette option active les &quot;crash dumps&quot; pour Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Activer Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
- <translation type="unfinished"/>
+ <translation>Lorsqu&apos;il est coché, il videra tous les shaders d&apos;assemblage d&apos;origine du cache de shader de disque ou du jeu tels qu&apos;ils ont été trouvés</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation>Récupérer Shaders Jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
- <translation type="unfinished"/>
+ <translation>Lorsqu&apos;il est coché, il videra tous les programmes de macro du GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>Lorsque coché, désactive le compilateur de macros JIT. L&apos;activer ralentit les jeux</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Désactiver les macros JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>Lorsque la case est cochée, yuzu enregistrera les journaux de statistiques à propos de la cache de pipeline compilée</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>Activer le retour d&apos;information des shaders</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>Lorsque la case est cochée, exécuter les shaders sans changer la boucle de logique</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>Désactiver les vérifications de boucle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Débogage</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>Activer les services de rapport verbeux**</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
<source>Enable FS Access Log</source>
<translation>Activer la journalisation des accès du système de fichiers</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
- <translation type="unfinished"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
+ <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
+ <translation>Activez cette option pour afficher la dernière liste de commandes audio générée sur la console. N&apos;affecte que les jeux utilisant le moteur de rendu audio.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
- <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>Activer les services de rapport verbeux**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Avancé</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Mode Kiosk (Quest)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Activer le Débogage CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Activer les assertions de débogage</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>Activer l&apos;Auto-Stub**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
- <translation type="unfinished"/>
+ <translation>Activer tous les types de contrôleurs</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Désactiver l&apos;applet web</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Ces options seront réinitialisées automatiquement lorsque yuzu fermera.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1242,7 +1292,7 @@ Cette option améliore la vitesse en réduisant la précision des instructions f
<message>
<location filename="../../src/yuzu/configuration/configure_general.ui" line="67"/>
<source>Extended memory layout (6GB DRAM)</source>
- <translation type="unfinished"/>
+ <translation>Disposition de la mémoire étendue (6GB DRAM)</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_general.ui" line="74"/>
@@ -1544,7 +1594,7 @@ Cette option améliore la vitesse en réduisant la précision des instructions f
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="78"/>
<source>Use VSync</source>
- <translation type="unfinished"/>
+ <translation>Utiliser VSync</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="85"/>
@@ -1567,37 +1617,47 @@ Cette option améliore la vitesse en réduisant la précision des instructions f
<translation>Utiliser le Temps GPU Rapide (Hack)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Filtrage anisotropique :</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>Automatique</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Défaut</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -1997,7 +2057,7 @@ Cette option améliore la vitesse en réduisant la précision des instructions f
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2623"/>
<source>Infrared Camera</source>
- <translation type="unfinished"/>
+ <translation>Caméra infrarouge</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2640"/>
@@ -2089,7 +2149,7 @@ Cette option améliore la vitesse en réduisant la précision des instructions f
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Stick Gauche</translation>
</message>
@@ -2183,14 +2243,14 @@ Cette option améliore la vitesse en réduisant la précision des instructions f
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2209,7 +2269,7 @@ Cette option améliore la vitesse en réduisant la précision des instructions f
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Plus</translation>
</message>
@@ -2222,15 +2282,15 @@ Cette option améliore la vitesse en réduisant la précision des instructions f
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2287,231 +2347,236 @@ Cette option améliore la vitesse en réduisant la précision des instructions f
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Stick Droit</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Effacer</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[non défini]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Bouton d&apos;activation</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>Inverser les boutons</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Bouton d&apos;activation</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Inverser l&apos;axe</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>Définir le seuil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Choisissez une valeur entre 0% et 100%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation>Définir le seuil du gyroscope</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Mapper le stick analogique</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Après avoir appuyé sur OK, bougez d&apos;abord votre joystick horizontalement, puis verticalement.
Pour inverser les axes, bougez d&apos;abord votre joystick verticalement, puis horizontalement.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
- <translation type="unfinished"/>
+ <translation>Axe central</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Zone morte : %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Modification de la course : %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Deux Joycons</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Joycon de gauche</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Joycon de droit</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Mode Portable</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>Manette GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>Poké Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>Manette NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>Manette SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>Manette N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Start / Pause</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Stick de contrôle </translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Secouez !</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[en attente]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Nouveau Profil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Entrez un nom de profil :</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Créer un profil d&apos;entrée </translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>Le nom de profil donné est invalide !</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Échec de la création du profil d&apos;entrée &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Supprimer le profil d&apos;entrée</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Échec de la suppression du profil d&apos;entrée &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Charger le profil d&apos;entrée</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Échec du chargement du profil d&apos;entrée &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Sauvegarder le profil d&apos;entrée</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Échec de la sauvegarde du profil d&apos;entrée &quot;%1&quot;</translation>
</message>
@@ -2766,42 +2831,42 @@ Pour inverser les axes, bougez d&apos;abord votre joystick verticalement, puis h
<translation>Développeur</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Extensions</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Général</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Système</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Graphiques</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Adv. Graphiques</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Audio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Propriétés</translation>
</message>
@@ -2995,7 +3060,7 @@ Pour inverser les axes, bougez d&apos;abord votre joystick verticalement, puis h
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="26"/>
<source>If you want to use this controller configure player 1 as right controller and player 2 as dual joycon before starting the game to allow this controller to be detected properly.</source>
- <translation type="unfinished"/>
+ <translation>Si vous souhaitez utiliser cette manette, configurez le joueur 1 comme manette droite et le joueur 2 comme double joycon avant de lancer le jeu pour permettre à cette manette d&apos;être détectée correctement.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="52"/>
@@ -3006,13 +3071,13 @@ Pour inverser les axes, bougez d&apos;abord votre joystick verticalement, puis h
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="84"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="123"/>
<source>Pull</source>
- <translation type="unfinished"/>
+ <translation>Tirer</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="133"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="172"/>
<source>Push</source>
- <translation type="unfinished"/>
+ <translation>Pousser</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="206"/>
@@ -3513,47 +3578,47 @@ Pour inverser les axes, bougez d&apos;abord votre joystick verticalement, puis h
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Lit l&apos;entrée du contrôleur à partir des scripts dans le même format que &apos;TAS-nx&apos; &lt;br/&gt; Pour une explication plus détaillée, veuillez consulter le &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;page d&apos;aide &lt;/span&gt;&lt;/a&gt;sur le site Yuzu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>Pour vérifier quelles touches de raccourci contrôlent la lecture/l&apos;enregistrement, veuillez vous reporter aux paramètres des touches de raccourci (Configurer -&gt; Général -&gt; Touches de raccourci).</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>AVERTISSEMENT : Cette fonctionnalité est expérimentale.&lt;br/&gt;Elle n&apos;exécutera pas les scripts à l&apos;image près avec l&apos;actuelle méthode, imparfaite, de synchronisation.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Paramètres</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>Activer les fonctions TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>Script de boucle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>Mettre en pause l&apos;exécution pendant le chargement</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>Dossier de script</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Chemin</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3869,7 +3934,7 @@ Faites glisser les points pour modifier la position ou double-cliquez sur les ce
<message>
<location filename="../../src/yuzu/configuration/configure_vibration.ui" line="23"/>
<source>Press any controller button to vibrate the controller.</source>
- <translation type="unfinished"/>
+ <translation>Appuyez sur n&apos;importe quel bouton du contrôleur pour faire vibrer le contrôleur.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_vibration.ui" line="30"/>
@@ -3963,7 +4028,7 @@ Faites glisser les points pour modifier la position ou double-cliquez sur les ce
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Vérifier</translation>
</message>
@@ -3990,7 +4055,7 @@ Faites glisser les points pour modifier la position ou double-cliquez sur les ce
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="118"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
- <translation type="unfinished"/>
+ <translation>La configuration du service Web ne peut être modifiée que lorsqu&apos;une salle publique n&apos;est pas hébergée.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="128"/>
@@ -4050,7 +4115,7 @@ Faites glisser les points pour modifier la position ou double-cliquez sur les ce
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Non-spécifié</translation>
</message>
@@ -4065,17 +4130,36 @@ Faites glisser les points pour modifier la position ou double-cliquez sur les ce
<translation>Le token n&apos;a pas été vérifié. Le changement à votre token n&apos;a pas été enregistré.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Vérification...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
+ <source>Verification failed</source>
+ <comment>Tooltip</comment>
+ <translation>Échec de la vérification</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
<source>Verification failed</source>
<translation>Échec de la vérification</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Échec de la vérification. Vérifiez si vous avez correctement entrez votre token, et que votre connection internet fonctionne.</translation>
</message>
@@ -4113,7 +4197,7 @@ Faites glisser les points pour modifier la position ou double-cliquez sur les ce
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="63"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;IPv4 address of the host&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Adresse IPv4 de l&apos;hôte&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="73"/>
@@ -4123,7 +4207,7 @@ Faites glisser les points pour modifier la position ou double-cliquez sur les ce
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="80"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Port number the host is listening on&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Numéro de port sur lequel l&apos;hôte écoute&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="100"/>
@@ -4138,928 +4222,909 @@ Faites glisser les points pour modifier la position ou double-cliquez sur les ce
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="156"/>
<source>Connect</source>
- <translation type="unfinished"/>
+ <translation>Connecter</translation>
</message>
</context>
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
- <translation type="unfinished"/>
+ <translation>Connexion</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
- <translation type="unfinished"/>
+ <translation>Connecter</translation>
</message>
</context>
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Des données anonymes sont collectées&lt;/a&gt; pour aider à améliorer yuzu. &lt;br/&gt;&lt;br/&gt;Voulez-vous partager vos données d&apos;utilisations avec nous ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Télémétrie</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Installation Vulkan Cassée Détectée</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
- <translation type="unfinished"/>
+ <translation>L&apos;initialisation de Vulkan a échoué lors du démarrage.&lt;br&gt;&lt;br&gt;Cliquez &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;ici pour obtenir des instructions pour résoudre le problème&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Chargement du Web Applet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Désactiver l&apos;applet web</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
- <translation type="unfinished"/>
+ <translation>La désactivation de l&apos;applet Web peut entraîner un comportement indéfini et ne doit être utilisée qu&apos;avec Super Mario 3D All-Stars. Voulez-vous vraiment désactiver l&apos;applet Web ?
+(Cela peut être réactivé dans les paramètres de débogage.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>La quantité de shaders en cours de construction</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Le multiplicateur de mise à l&apos;échelle de résolution actuellement sélectionné.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Valeur actuelle de la vitesse de l&apos;émulation. Des valeurs plus hautes ou plus basses que 100% indique que l&apos;émulation fonctionne plus vite ou plus lentement qu&apos;une véritable Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Combien d&apos;image par seconde le jeu est en train d&apos;afficher. Ceci vas varier de jeu en jeu et de scènes en scènes.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Temps pris pour émuler une image par seconde de la switch, sans compter le limiteur d&apos;image par seconde ou la synchronisation verticale. Pour une émulation à pleine vitesse, ceci devrait être au maximum à 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Effacer les fichiers récents</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>&amp;Continuer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Pause</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>yuzu exécute un jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Avertissement : Le Format de jeu est dépassé</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Vous utilisez un format de ROM déconstruite pour ce jeu, qui est donc un format dépassé qui à été remplacer par d&apos;autre. Par exemple les formats NCA, NAX, XCI, ou NSP. Les destinations de ROM déconstruites manque des icônes, des métadonnée et du support de mise à jour.&lt;br&gt;&lt;br&gt;Pour une explication des divers formats Switch que yuzu supporte, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;Regardez dans le wiki&lt;/a&gt;. Ce message ne sera pas montré une autre fois.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Erreur lors du chargement de la ROM !</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>Le format de la ROM n&apos;est pas supporté.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Une erreur s&apos;est produite lors de l&apos;initialisation du noyau dédié à la vidéo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu a rencontré une erreur en exécutant le cœur vidéo. Cela est généralement causé par des pilotes graphiques trop anciens. Veuillez consulter les logs pour plus d&apos;informations. Pour savoir comment accéder aux logs, veuillez vous référer à la page suivante : &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Comment partager un fichier de log &lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Erreur lors du chargement de la ROM ! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Veuillez suivre &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;le guide de démarrage rapide yuzu&lt;/a&gt; pour retransférer vos fichiers.&lt;br&gt;Vous pouvez vous référer au wiki yuzu&lt;/a&gt; ou le Discord yuzu&lt;/a&gt; pour de l&apos;assistance.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Une erreur inconnue est survenue. Veuillez consulter le journal des logs pour plus de détails.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Enregistrer les données</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Donnés du Mod</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Erreur dans l&apos;ouverture du dossier %1.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Le dossier n&apos;existe pas !</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Erreur lors de l&apos;ouverture des Shader Cache Transferable</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Impossible de créer le dossier de cache du shader pour ce jeu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Contenus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Mise à jour</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Supprimer l&apos;entrée</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>Supprimer le jeu installé %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>Supprimé avec succès</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>Suppression du jeu de base installé avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>Erreur lors de la suppression %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Le jeu de base n&apos;est pas installé dans la NAND et ne peut pas être supprimé.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>Suppression de la mise à jour installée avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>Il n&apos;y a pas de mise à jour installée pour ce titre.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>Il n&apos;y a pas de DLC installé pour ce titre.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Suppression de %1 DLC installé(s) avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Supprimer la Cache OpenGL de Shader Transférable?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Supprimer la Cache Vulkan de Shader Transférable?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Supprimer Toutes les Caches de Shader Transférable?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>Supprimer la configuration personnalisée du jeu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Supprimer fichier</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Erreur lors de la suppression du cache de shader transférable</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>Un shader cache pour ce titre n&apos;existe pas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Suppression du cache de shader transférable avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Échec de la suppression du cache de shader transférable.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Erreur durant la Suppression des Caches de Shader Transférable</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Suppression des caches de shader transférable effectuée avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Impossible de supprimer le dossier de la cache de shader transférable.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Erreur lors de la suppression de la configuration personnalisée</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Il n&apos;existe pas de configuration personnalisée pour ce titre.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Suppression de la configuration de jeu personnalisée avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Échec de la suppression de la configuration personnalisée du jeu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>L&apos;extraction de la RomFS a échoué !</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Une erreur s&apos;est produite lors de la copie des fichiers RomFS ou l&apos;utilisateur a annulé l&apos;opération.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Plein</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Squelette</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Sélectionnez le mode d&apos;extraction de la RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Veuillez sélectionner la manière dont vous souhaitez que le fichier RomFS soit extrait.&lt;br&gt;Full copiera tous les fichiers dans le nouveau répertoire, tandis que&lt;br&gt;skeleton créera uniquement la structure de répertoires.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Il n&apos;y a pas assez d&apos;espace libre dans %1 pour extraire la RomFS. Veuillez libérer de l&apos;espace ou sélectionner un autre dossier d&apos;extraction dans Émulation &gt; Configurer &gt; Système &gt; Système de fichiers &gt; Extraire la racine</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Extraction de la RomFS ...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Annuler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Extraction de la RomFS réussi !</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>L&apos;opération s&apos;est déroulée avec succès.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Erreur lors de l&apos;ouverture %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Sélectionner un répertoire</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Propriétés</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Les propriétés du jeu n&apos;ont pas pu être chargées.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Exécutable Switch (%1);;Tous les fichiers (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Charger un fichier</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Ouvrir le dossier des ROM extraites</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Destination sélectionnée invalide</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Le répertoire que vous avez sélectionné ne contient pas de fichier &quot;main&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Fichier Switch installable (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Installer les fichiers</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n fichier restant</numerusform><numerusform>%n fichiers restants</numerusform><numerusform>%n fichiers restants</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Installation du fichier &quot;%1&quot; ...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Résultats d&apos;installation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Pour éviter d&apos;éventuels conflits, nous déconseillons aux utilisateurs d&apos;installer des jeux de base sur la NAND.
Veuillez n&apos;utiliser cette fonctionnalité que pour installer des mises à jour et des DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n fichier a été nouvellement installé</numerusform><numerusform>%n fichiers ont été nouvellement installés</numerusform><numerusform>%n fichiers ont été nouvellement installés</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n fichier a été écrasé</numerusform><numerusform>%n fichiers ont été écrasés</numerusform><numerusform>%n fichiers ont été écrasés</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n fichier n&apos;a pas pu être installé</numerusform><numerusform>%n fichiers n&apos;ont pas pu être installés</numerusform><numerusform>%n fichiers n&apos;ont pas pu être installés</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Application Système</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Archive Système</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Mise à jour de l&apos;application système</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Paquet micrologiciel (Type A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Paquet micrologiciel (Type B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Mise à jour de jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>DLC de jeu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Titre Delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Sélectionner le type d&apos;installation du NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Veuillez sélectionner le type de titre auquel vous voulez installer ce NCA :
(Dans la plupart des cas, le titre par défaut : &apos;Jeu&apos; est correct.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Échec de l&apos;installation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Le type de titre que vous avez sélectionné pour le NCA n&apos;est pas valide.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Fichier non trouvé</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Fichier &quot;%1&quot; non trouvé</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Compte yuzu manquant</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Pour soumettre un test de compatibilité pour un jeu, vous devez lier votre compte yuzu.&lt;br&gt;&lt;br/&gt;Pour lier votre compte yuzu, aller à Emulation &amp;gt; Configuration&amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Erreur lors de l&apos;ouverture de l&apos;URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Impossible d&apos;ouvrir l&apos;URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>Enregistrement TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>Écraser le fichier du joueur 1 ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>Configuration invalide détectée</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Contrôleur portable ne peut pas être utilisé en mode téléviseur. La manette Pro sera sélectionnée.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>Erreur</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation>Le jeu actuel ne cherche pas d&apos;amiibos.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation>L&apos;amiibo actuel a été retiré</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Fichier Amiibo (%1);; Tous les fichiers (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Charger un Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Erreur lors de l&apos;ouverture du fichier de données Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Impossible d&apos;ouvrir le fichier Amiibo &quot;%1&quot; à lire.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Erreur lors de la lecture du fichier de données Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Impossible de lire entièrement les données Amiibo. On s&apos;attend à lire %1 octets, mais il n&apos;a pu lire que %2 octets</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Erreur lors du chargement des données Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Impossible de charger les données Amiibo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Capture d&apos;écran</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>Image PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>État du TAS : En cours d&apos;exécution %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>État du TAS : Enregistrement %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>État du TAS : Inactif %1:%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>État du TAS : Invalide</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>&amp;Stopper l&apos;exécution</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>Stopper l&apos;en&amp;registrement</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>En&amp;registrer</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Compilation: %n shader</numerusform><numerusform>Compilation : %n shaders</numerusform><numerusform>Compilation : %n shaders</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Échelle : %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Vitesse : %1% / %2% </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Vitesse : %1% </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Jeu : %1 IPS (Débloqué)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Jeu : %1 FPS </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Frame : %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU HAUT</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU EXTRÊME</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>GPU ERREUR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation>MODE TV</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation>PORTABLE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>PLUS PROCHE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>BILINÉAIRE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>BICUBIQUE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>GAUSSIEN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>AUCUN AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>Le jeu que vous essayez de charger a besoin de fichiers additionnels que vous devez extraire depuis votre Switch avant de jouer.&lt;br/&gt;&lt;br/&gt;Pour plus d&apos;information sur l&apos;extraction de ces fichiers, veuillez consulter la page du wiki suivante : &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Extraction des archives système et des Shared Fonts depuis la Switch&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Voulez-vous quitter la liste des jeux ? Une émulation continue peut entraîner des crashs, la corruption de données de sauvegarde ou d’autres bugs.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>yuzu n&apos;a pas été capable de localiser un système d&apos;archive Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>yuzu n&apos;a pas été capable de localiser un système d&apos;archive Switch. %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Archive système introuvable</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Archive Système Manquante</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>Yuzu n&apos;a pas été capable de localiser les polices partagées de la Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Les polices partagées non pas été trouvées</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Police Partagée Manquante</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Erreur fatale</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu a rencontré une erreur fatale, veuillez consulter les logs pour plus de détails. Pour plus d&apos;informations sur l&apos;accès aux logs, veuillez consulter la page suivante : &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt; Comment télécharger le fichier des logs &lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Voulez-vous quitter la liste des jeux ? Une émulation continue peut entraîner des crashs, la corruption de données de sauvegarde ou d’autres bugs.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Erreur Fatale rencontrée</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Confirmer la réinstallation de la clé</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5076,37 +5141,37 @@ et éventuellement faites des sauvegardes.
Cela supprimera vos fichiers de clé générés automatiquement et ré exécutera le module d&apos;installation de clé.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>Fusibles manquants</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation>- BOOT0 manquant</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- BCPKG2-1-Normal-Main manquant</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation>- PRODINFO manquant</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>Composants de dérivation manquants</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Les clés de chiffrement sont manquantes. &lt;br&gt;Veuillez suivre &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;le guide de démarrage rapide yuzu&lt;/a&gt; pour obtenir tous vos clés, firmware et jeux.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5115,39 +5180,39 @@ Cela peut prendre jusqu&apos;à une minute en fonction
des performances de votre système.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Installation des clés</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Sélectionner la cible d&apos;extraction du RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Veuillez sélectionner quel RomFS vous voulez extraire.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Êtes vous sûr de vouloir fermer yuzu ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Êtes-vous sûr d&apos;arrêter l&apos;émulation ? Tout progrès non enregistré sera perdu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5486,7 +5551,7 @@ Screen.</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="101"/>
<source>(Leave blank for open game)</source>
- <translation type="unfinished"/>
+ <translation>(Laisser vide pour ouvrir le jeu)</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="118"/>
@@ -5506,7 +5571,7 @@ Screen.</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="153"/>
<source>Load Previous Ban List</source>
- <translation type="unfinished"/>
+ <translation>Charger la liste de bannissement précédente</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="184"/>
@@ -5527,25 +5592,27 @@ Screen.</source>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>Erreur</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
- <translation type="unfinished"/>
+ <translation>Échec de l&apos;annonce de la salle dans le hall public. Pour héberger une salle publiquement, vous devez avoir un compte yuzu valide configuré dans Emulation -&gt; Configurer -&gt; Web. Si vous ne souhaitez pas publier une salle dans le hall public, sélectionnez plutôt Non Répertorié.
+Message de débogage : </translation>
</message>
</context>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
- <translation type="unfinished"/>
+ <translation>Désactiver/Activer le Son</translation>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5567,114 +5634,113 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
- <translation type="unfinished"/>
+ <translation>Fenêtre Principale</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
- <translation type="unfinished"/>
+ <translation>Baisser le volume audio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
- <translation type="unfinished"/>
+ <translation>Augmenter le volume audio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Prendre une capture d&apos;ecran</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
- <translation type="unfinished"/>
+ <translation>Modifier le filtre d&apos;adaptation</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
- <translation type="unfinished"/>
+ <translation>Changer le mode de la station d&apos;accueil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
- <translation type="unfinished"/>
+ <translation>Modifier la précision du GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation>Continuer/Suspendre l&apos;Émulation</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation>Quitter le plein écran</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation>Quitter yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Plein écran</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Charger un fichier</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation>Charger/Supprimer un Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation>Redémarrer l&apos;Émulation</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation>Arrêter l&apos;Émulation</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
- <translation type="unfinished"/>
+ <translation>Enregistrement TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
- <translation type="unfinished"/>
+ <translation>Réinitialiser le TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
- <translation type="unfinished"/>
+ <translation>Démarrer/Arrêter le TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
- <translation type="unfinished"/>
+ <translation>Activer la barre de filtre</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
- <translation type="unfinished"/>
+ <translation>Activer la limite de fréquence d&apos;images</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
- <translation type="unfinished"/>
+ <translation>Activer le panoramique de la souris</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
- <translation type="unfinished"/>
+ <translation>Activer la barre d&apos;état</translation>
</message>
</context>
<context>
@@ -5787,42 +5853,42 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
- <translation type="unfinished"/>
+ <translation>Mot de passe requis pour rejoindre</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation>Mot de passe:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation>Nom du salon</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation>Jeu préféré</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation>Hôte</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Joueurs</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation>Rafraîchissement</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation>Rafraîchir la liste</translation>
</message>
@@ -5997,12 +6063,12 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/main.ui" line="275"/>
<source>Direct Connect to Room</source>
- <translation type="unfinished"/>
+ <translation>Connexion directe au salon</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="283"/>
<source>Show Current Room</source>
- <translation type="unfinished"/>
+ <translation>Afficher le salon actuel</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="291"/>
@@ -6088,12 +6154,12 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="6"/>
<source>Moderation</source>
- <translation type="unfinished"/>
+ <translation>Modération</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="20"/>
<source>Ban List</source>
- <translation type="unfinished"/>
+ <translation>Liste de bannissement</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="41"/>
@@ -6104,22 +6170,22 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="51"/>
<source>Unban</source>
- <translation type="unfinished"/>
+ <translation>Débannir</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="40"/>
<source>Subject</source>
- <translation type="unfinished"/>
+ <translation>Sujet</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="41"/>
<source>Type</source>
- <translation type="unfinished"/>
+ <translation>Type</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="83"/>
<source>Forum Username</source>
- <translation type="unfinished"/>
+ <translation>Nom d&apos;utilisateur du forum</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="88"/>
@@ -6138,18 +6204,18 @@ Debug Message: </source>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="47"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="91"/>
<source>Current connection status</source>
- <translation type="unfinished"/>
+ <translation>État actuel de la connexion</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="48"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="94"/>
<source>Not Connected. Click here to find a room!</source>
- <translation type="unfinished"/>
+ <translation>Pas connecté. Cliquez ici pour trouver un salon !</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Connecté</translation>
</message>
@@ -6171,9 +6237,9 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
- <translation type="unfinished"/>
+ <translation>Nouveaux messages reçus</translation>
</message>
</context>
<context>
@@ -6181,62 +6247,62 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="11"/>
<source>Username is not valid. Must be 4 to 20 alphanumeric characters.</source>
- <translation type="unfinished"/>
+ <translation>Le nom d&apos;utilisateur n&apos;est pas valide. Doit être de 4 à 20 caractères alphanumériques.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="13"/>
<source>Room name is not valid. Must be 4 to 20 alphanumeric characters.</source>
- <translation type="unfinished"/>
+ <translation>Le nom du salon n&apos;est pas valide. Doit être de 4 à 20 caractères alphanumériques.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="15"/>
<source>Username is already in use or not valid. Please choose another.</source>
- <translation type="unfinished"/>
+ <translation>Le nom d&apos;utilisateur est déjà utilisé ou n&apos;est pas valide. Veuillez en sélectionner un autre.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="17"/>
<source>IP is not a valid IPv4 address.</source>
- <translation type="unfinished"/>
+ <translation>IP n&apos;est pas une adresse IPv4 valide.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="19"/>
<source>Port must be a number between 0 to 65535.</source>
- <translation type="unfinished"/>
+ <translation>Le port doit être un nombre compris entre 0 et 65535.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="20"/>
<source>You must choose a Preferred Game to host a room. If you do not have any games in your game list yet, add a game folder by clicking on the plus icon in the game list.</source>
- <translation type="unfinished"/>
+ <translation>Vous devez choisir un jeu préféré pour héberger un salon. Si vous n&apos;avez pas encore de jeux dans votre liste de jeux, ajoutez un dossier de jeu en cliquant sur l&apos;icône plus dans la liste de jeux.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="24"/>
<source>Unable to find an internet connection. Check your internet settings.</source>
- <translation type="unfinished"/>
+ <translation>Impossible de trouver une connexion Internet. Vérifiez vos paramètres Internet.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="26"/>
<source>Unable to connect to the host. Verify that the connection settings are correct. If you still cannot connect, contact the room host and verify that the host is properly configured with the external port forwarded.</source>
- <translation type="unfinished"/>
+ <translation>Impossible de se connecter à l&apos;hôte. Vérifiez que les paramètres de connexion sont corrects. Si vous ne parvenez toujours pas à vous connecter, contactez l&apos;hôte de la salle et vérifiez que l&apos;hôte a correctement configuré le port externe redirigé.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="30"/>
<source>Unable to connect to the room because it is already full.</source>
- <translation type="unfinished"/>
+ <translation>Impossible de se connecter au salon car il est déjà plein.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="32"/>
<source>Creating a room failed. Please retry. Restarting yuzu might be necessary.</source>
- <translation type="unfinished"/>
+ <translation>La création d&apos;un salon a échoué. Veuillez réessayer. Peut être que vous devriez redémarrer yuzu.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="34"/>
<source>The host of the room has banned you. Speak with the host to unban you or try a different room.</source>
- <translation type="unfinished"/>
+ <translation>L&apos;hôte du salon vous a banni. Parlez à l&apos;hôte pour vous débannir ou essayez un autre salon.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="37"/>
<source>Version mismatch! Please update to the latest version of yuzu. If the problem persists, contact the room host and ask them to update the server.</source>
- <translation type="unfinished"/>
+ <translation>Décalage de version ! Veuillez mettre à jour la dernière version de yuzu. Si le problème persiste, contactez l&apos;hôte de la salle et demandez lui de mettre à jour le serveur.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="39"/>
@@ -6251,54 +6317,74 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="43"/>
<source>Connection to room lost. Try to reconnect.</source>
- <translation type="unfinished"/>
+ <translation>Connexion au salon perdue. Essayez de vous reconnecter.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="45"/>
<source>You have been kicked by the room host.</source>
- <translation type="unfinished"/>
+ <translation>Vous avez été expulsé par l&apos;hôte du salon.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="47"/>
<source>IP address is already in use. Please choose another.</source>
- <translation type="unfinished"/>
+ <translation>L&apos;adresse IP est déjà utilisée. Veuillez en sélectionner une autre.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="49"/>
<source>You do not have enough permission to perform this action.</source>
- <translation type="unfinished"/>
+ <translation>Vous ne disposez pas des autorisations suffisantes pour effectuer cette action.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="50"/>
<source>The user you are trying to kick/ban could not be found.
They may have left the room.</source>
- <translation type="unfinished"/>
+ <translation>L&apos;utilisateur que vous essayez d&apos;exclure/bannir est introuvable.
+Il a peut-être quitté la salon.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation>Aucune interface réseau n&apos;est sélectionnée.
+Allez dans Configurer -&gt; Système -&gt; Réseau et faites une sélection.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation>Jeu déjà en cours</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation>Rejoindre un salon lorsque le jeu est déjà en cours d&apos;exécution est déconseillé et peut empêcher le salon de fonctionner correctement.
+Continuer quand même ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation>Quitter le salon</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
- <translation type="unfinished"/>
+ <translation>Vous êtes sur le point de fermer le salon. Toutes les connexions réseau seront fermées.</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
- <translation type="unfinished"/>
+ <translation>Déconnecter</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
- <translation type="unfinished"/>
+ <translation>Vous êtes sur le point de quitter le salon. Toutes les connexions réseau seront fermées.</translation>
</message>
</context>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>Erreur</translation>
</message>
@@ -6349,15 +6435,15 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/multiplayer/lobby_p.h" line="230"/>
<source>%1 is not playing a game</source>
- <translation type="unfinished"/>
+ <translation>%1 ne joue pas à un jeu</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby_p.h" line="232"/>
<source>%1 is playing %2</source>
- <translation type="unfinished"/>
+ <translation>%1 joue à %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation>Ne joue pas à un jeu</translation>
</message>
@@ -6412,7 +6498,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[non défini]</translation>
</message>
@@ -6427,10 +6513,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Axe %1%2</translation>
</message>
@@ -6444,9 +6530,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[inconnu]</translation>
</message>
@@ -6611,15 +6697,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[invalide]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation>%1%2Chapeau %3</translation>
</message>
@@ -6627,35 +6713,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation>%1%2Axe %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation>%1%2Axe %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2Mouvement %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2Bouton %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[inutilisé]</translation>
</message>
@@ -6696,7 +6782,7 @@ p, li { white-space: pre-wrap; }
<translation>Extra</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/languages/id.ts b/dist/languages/id.ts
index 7a9b2a6c0..da09ad113 100644
--- a/dist/languages/id.ts
+++ b/dist/languages/id.ts
@@ -89,78 +89,78 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -730,200 +730,235 @@ Memungkinkan berbagai macam optimasi IR.</translation>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Aktifkan GDB Stub</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Port:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Pencatatan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Catatan Penyaring Global</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Tampilkan Catatan Di Konsol</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Buka Lokasi Catatan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Saat dicentang, ukuran maksimum log meningkat dari 100 MB menjadi 1 GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Aktifkan Pencatatan Yang Diperluas**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>String Argumen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Grafis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Nyalakan Pengawakutuan Grafis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Aktifkan Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>Saat dicentang, ini menonaktifkan kompiler makro Just In Time. Mengaktifkan ini membuat game berjalan lebih lambat</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Matikan Macro JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>Saat dinyalakan, yuzu akan mencatat statstik tentang pipeline cache yang disusun</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>Nyalakan Umpan Balik Shader</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>Saat dinyalakan, akan menjalankan shader tanpa perubahan logika loop</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>Matikan cek keamanan Loop</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Pengawakutuan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>Nyalakan Layanan Laporan Bertele-tele**</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
<source>Enable FS Access Log</source>
<translation>Nyalakan Log Akses FS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
+ <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
- <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>Nyalakan Layanan Laporan Bertele-tele**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Lanjutan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Mode Kiosk (Pencarian)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Nyalakan Pengawakutuan CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Nyalakan Awakutu Assert</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation>Aktifkan Semua Jenis Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Matikan Applet Web</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Ini akan diatur ulang secara otomatis ketika yuzu ditutup.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1542,37 +1577,47 @@ Memungkinkan berbagai macam optimasi IR.</translation>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Anisotropic Filtering:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>Otomatis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Bawaan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2064,7 +2109,7 @@ Memungkinkan berbagai macam optimasi IR.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Stik Kiri</translation>
</message>
@@ -2158,14 +2203,14 @@ Memungkinkan berbagai macam optimasi IR.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2184,7 +2229,7 @@ Memungkinkan berbagai macam optimasi IR.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Tambah</translation>
</message>
@@ -2197,15 +2242,15 @@ Memungkinkan berbagai macam optimasi IR.</translation>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2262,231 +2307,236 @@ Memungkinkan berbagai macam optimasi IR.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Stik Kanan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Bersihkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[belum diatur]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Atur tombol</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>Balikkan tombol</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Atur tombol</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Balikkan poros</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>Atur batasan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Pilih sebuah angka diantara 0% dan 100%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Petakan Stik Analog</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Setelah menekan OK, pertama gerakkan joystik secara mendatar, lalu tegak lurus.
Untuk membalikkan sumbu, pertama gerakkan joystik secara tegak lurus, lalu mendatar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Titik Mati: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Rentang Pengubah: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Kontroler Pro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Joycon Dual</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Joycon Kiri</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Joycon Kanan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Jinjing</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>Kontroler GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>Kontroler NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>Kontroler SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>Kontroler N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Mulai / Jeda</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Stik Kendali</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Getarkan!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[menunggu]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Profil Baru</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Masukkan nama profil:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Ciptakan Profil Masukan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>Nama profil yang diberi tidak sah!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Gagal membuat profil masukan &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Hapus Profil Masukan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Gagal menghapus profil masukan &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Muat Profil Masukan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Gagal memuat profil masukan &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Simpat Profil Masukan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Gagal menyimpan profil masukan &quot;%1&quot;</translation>
</message>
@@ -2741,42 +2791,42 @@ Untuk membalikkan sumbu, pertama gerakkan joystik secara tegak lurus, lalu menda
<translation>Pengembang</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Pengaya (Add-On)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Umum</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Sistem</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Grafis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Ljtan. Grafik</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Audio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Properti</translation>
</message>
@@ -3488,47 +3538,47 @@ Untuk membalikkan sumbu, pertama gerakkan joystik secara tegak lurus, lalu menda
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Pengaturan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Jalur</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3937,7 +3987,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Verifikasi</translation>
</message>
@@ -4024,7 +4074,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Tak dispesifikasikan</translation>
</message>
@@ -4039,17 +4089,36 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Token tidak terverifikasi. Perubahan ke token Anda tak tersimpan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Memverifikasi...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Verifikasi gagal</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Verifikasi gagal</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Pemverifikasian gagal. Periksa apakah token yang dimasukkan sudah benar dan apakah koneksi internet Anda berjalan.</translation>
</message>
@@ -4118,12 +4187,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation type="unfinished"/>
</message>
@@ -4131,911 +4200,891 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Data anonim dikumpulkan&lt;/a&gt; untuk membantu yuzu. &lt;br/&gt;&lt;br/&gt;Apa Anda ingin membagi data penggunaan dengan kami?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Memuat Applet Web...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Matikan Applet Web</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>Jumlah shader yang sedang dibuat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Pengali skala resolusi yang terpilih.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Kecepatan emulasi saat ini. Nilai yang lebih tinggi atau rendah dari 100% menandakan pengemulasian berjalan lebih cepat atau lambat dibanding Switch aslinya.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Berapa banyak frame per second (bingkai per detik) permainan akan ditampilkan. Ini akan berubah dari berbagai permainan dan pemandangan.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Waktu yang diperlukan untuk mengemulasikan bingkai Switch, tak menghitung pembatas bingkai atau v-sync. Agar emulasi berkecepatan penuh, ini harus 16.67 mdtk.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Bersihkan Berkas Baru-baru Ini</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>&amp;Lanjutkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Jeda</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>yuzu sedang menjalankan game</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Peringatan Format Permainan yang Usang</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Anda menggunakan format direktori ROM yang sudah didekonstruksi untuk permainan ini, yang mana itu merupakan format lawas yang sudah tergantikan oleh yang lain seperti NCA, NAX, XCI, atau NSP. Direktori ROM yang sudah didekonstruksi kekurangan ikon, metadata, dan dukungan pembaruan.&lt;br&gt;&lt;br&gt;Untuk penjelasan berbagai format Switch yang didukung yuzu, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;periksa wiki kami&lt;/a&gt;. Pesan ini tidak akan ditampilkan lagi.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Kesalahan ketika memuat ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>Format ROM tak didukung.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Terjadi kesalahan ketika menginisialisasi inti video.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu telah mengalami error saat menjalankan inti video. Ini biasanya disebabkan oleh pemicu piranti (driver) GPU yang usang, termasuk yang terintegrasi. Mohon lihat catatan untuk informasi lebih rinci. Untuk informasi cara mengakses catatan, mohon lihat halaman berikut: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Cara Mengupload Berkas Catatan&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Terjadi kesalahan yang tak diketahui. Mohon lihat catatan untuk informasi lebih rinci.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Simpan Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Mod Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Gagal Membuka Folder %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Folder tak ada!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Gagal Ketika Membuka Tembolok Shader yang Dapat Ditransfer</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Konten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Perbaharui</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Hapus Masukan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>Tidak ada DLC yang terinstall untuk judul ini.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Hapus File</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Kesalahan Menghapus Transferable Shader Cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>Cache shader bagi judul ini tidak ada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Kesalahan Menghapus Konfigurasi Buatan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>Pengekstrakan RomFS Gagal!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Terjadi kesalahan ketika menyalin berkas RomFS atau dibatalkan oleh pengguna.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Penuh</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Skeleton</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Pilih Mode Dump RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Mohon pilih cara RomFS akan di-dump.&lt;br&gt;FPenuh akan menyalin seluruh berkas ke dalam direktori baru sementara &lt;br&gt;jerangkong hanya akan menciptakan struktur direktorinya saja.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Mengekstrak RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Batal</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Pengekstrakan RomFS Berhasil!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>Operasi selesai dengan sukses,</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Gagal membuka %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Pilih Direktori</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Properti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Properti permainan tak dapat dimuat.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Eksekutabel Switch (%1);;Semua Berkas (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Muat Berkas</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Buka Direktori ROM Terekstrak</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Direktori Terpilih Tidak Sah</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Direktori yang Anda pilih tak memiliki berkas &apos;utama.&apos;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Install File</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Memasang berkas &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Hasil Install</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n file(s) baru diinstall
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n file(s) telah ditimpa
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n file(s) gagal di install
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Aplikasi Sistem</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Arsip Sistem</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Pembaruan Aplikasi Sistem</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Paket Perangkat Tegar (Tipe A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Paket Perangkat Tegar (Tipe B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Permainan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Pembaruan Permainan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>DLC Permainan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Judul Delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Pilih Tipe Pemasangan NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Mohon pilih jenis judul yang Anda ingin pasang sebagai NCA ini:
(Dalam kebanyakan kasus, pilihan bawaan &apos;Permainan&apos; tidak apa-apa`.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Gagal Memasang</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Jenis judul yang Anda pilih untuk NCA tidak sah.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Berkas tak ditemukan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Berkas &quot;%1&quot; tak ditemukan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Akun yuzu Hilang</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Agar dapat mengirimkan berkas uju kompatibilitas permainan, Anda harus menautkan akun yuzu Anda.&lt;br&gt;&lt;br/&gt;TUntuk mennautkan akun yuzu Anda, pergi ke Emulasi &amp;gt; Konfigurasi &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Kesalahan saat membuka URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Tidak dapat membuka URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>Rekaman TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>Timpa file pemain 1? </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>Konfigurasi tidak sah terdeteksi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Kontroller jinjing tidak bisa digunakan dalam mode dock. Kontroller Pro akan dipilih</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Berkas Amiibo (%1);; Semua Berkas (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Muat Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Gagal membuka berkas data Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Tak dapat membuka berkas Amiibo &quot;%1&quot; untuk dibaca.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Gagal membaca berkas data Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Tak dapat membaca data Amiibo sepenuhnya. Diperkirakan membaca %1 bita, namun hanya terbaca %2 bita.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Gagal memuat data Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Tak dapat memuat data Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Tangkapan Layar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>Berkas PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>Status TAS: Berjalan %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>Status TAS: Merekam %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>Status TAS: Diam %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>Status TAS: Tidak Valid</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>&amp;Matikan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Mulai</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>Berhenti Mer&amp;ekam</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>R&amp;ekam</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Membangun: %n shader(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Skala: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Kecepatan: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Kecepatan: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Permainan: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Frame: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU TINGGI</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU EKSTRIM</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>KESALAHAN GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>NEAREST</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>BILINEAR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>BICUBIC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>GAUSSIAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>TANPA AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Kesalahan Fatal</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5046,76 +5095,76 @@ This will delete your autogenerated key files and re-run the key derivation modu
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation>- Kehilangan BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- Kehilangan BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation>- Kehilangan PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Apakah anda yakin ingin menutup yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5490,12 +5539,12 @@ Screen.</source>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5504,11 +5553,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5530,112 +5580,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Tangkapan Layar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Muat Berkas</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5749,42 +5798,42 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Pemain</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation type="unfinished"/>
</message>
@@ -6111,7 +6160,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Terhubung</translation>
</message>
@@ -6133,7 +6182,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation type="unfinished"/>
</message>
@@ -6237,22 +6286,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6260,7 +6326,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
@@ -6315,7 +6381,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation type="unfinished"/>
</message>
@@ -6370,7 +6436,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[belum diatur]</translation>
</message>
@@ -6385,10 +6451,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation type="unfinished"/>
</message>
@@ -6402,9 +6468,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation type="unfinished"/>
</message>
@@ -6569,15 +6635,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation type="unfinished"/>
</message>
@@ -6585,35 +6651,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2Gerakan %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation type="unfinished"/>
</message>
@@ -6654,7 +6720,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation type="unfinished"/>
</message>
diff --git a/dist/languages/it.ts b/dist/languages/it.ts
index 76d639a4c..5995053de 100644
--- a/dist/languages/it.ts
+++ b/dist/languages/it.ts
@@ -95,78 +95,78 @@ p, li { white-space: pre-wrap; }
<translation>Invia messaggio</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation>Membri</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation>%1 è entrato</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation>%1 è uscito</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation>%1 è stato espulso</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation>%1 è stato bannato</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation>%1 non è più bannato</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation>Visualizza profilo</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation>Blocca giocatore</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation>Quando blocchi un giocatore, non riceverai più messaggi da quel giocatore.&lt;br&gt;&lt;br&gt;Sei sicuro di voler bloccare %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation>Espelli</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation>Banna</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation>Espelli giocatore</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation>Sei sicuro di voler &lt;b&gt;espellere&lt;/b&gt; %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation>Banna giocatore</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -282,7 +282,7 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
<message>
<location filename="../../src/yuzu/compatdb.ui" line="147"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Game is completely unplayable due to major graphical or audio glitches. Unable to progress past the Start Screen.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Questo gioco è completamente ingiocabile a causa di gravi errori audio o video. E&apos; impossibile proseguire oltre la schermata iniziale.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Il gioco è del tutto ingiocabile a causa di considerevoli glitch audio o video. È impossibile proseguire oltre la schermata iniziale.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="157"/>
@@ -297,7 +297,7 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
<message>
<location filename="../../src/yuzu/compatdb.ui" line="182"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Independent of speed or performance, how well does this game play from start to finish on this version of yuzu?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Indipendentemente da velocità o prestazioni, come ti è sembrato giocare questo gioco dall&apos;inizio alla fine su questa versione di yuzu?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Indipendentemente dalla velocità dalle prestazioni, come ti è sembrato giocare questo gioco dall&apos;inizio alla fine su questa versione di yuzu?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/compatdb.ui" line="206"/>
@@ -666,13 +666,13 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
&lt;div&gt;Enables IR optimizations that involve constant propagation.&lt;/div&gt;
</source>
<translation>
- &lt;div&gt;Abilita le ottimizzazioni dell&apos;IR che comportano una propagazione costante.&lt;/div&gt;
+ &lt;div&gt;Abilita le ottimizzazioni dell&apos;IR che comportano la propagazione delle costanti.&lt;/div&gt;
</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="108"/>
<source>Enable constant propagation</source>
- <translation>Abilita la propagazione costante</translation>
+ <translation>Abilita la propagazione delle costanti</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="115"/>
@@ -758,200 +758,235 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation>Debugger</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Abilita stub GDB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Porta:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Logging</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Filtro log globale</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Mostra i log nella console</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Apri cartella dei log</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
- <translation>Quando selezionata, la dimensione massima del log aumenterà da 100 MB a 1 GB</translation>
+ <translation>Quando l&apos;opzione è selezionata, la dimensione massima del log aumenterà da 100 MB a 1 GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Abilita il log esteso**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Stringa degli Argomenti</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Grafica</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
- <translation>Quando selezionata, l&apos;API entra in modalità di debug lento</translation>
+ <translation>Quando l&apos;opzione è selezionata, l&apos;API grafica entra in una modalità di debug più lenta</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Abilita Debugging Grafica</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
- <translation>Se spuntato, abilita i crash dump di Nsight Aftermath</translation>
+ <translation>Quando l&apos;opzione è selezionata, abilita i crash dump di Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Abilita Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
- <translation type="unfinished"/>
+ <translation>Estrai shader del gioco</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
- <translation type="unfinished"/>
+ <translation>Quando l&apos;opzione è selezionata, verranno estratti tutti i programmi macro della GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
- <translation type="unfinished"/>
+ <translation>Estrai macro Maxwell</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
- <translation>Quando selezionato, disabilita il macro-compilatore JIT. Abilitalo per rendere i giochi più lenti</translation>
+ <translation>Quando l&apos;opzione è selezionata, disabilita il compilatore Just-In-Time delle macro. Abilitare questa opzione rende i giochi più lenti</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
- <translation>Disabilita Macro JIT</translation>
+ <translation>Disabilita JIT macro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Debug</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
- <source>Enable FS Access Log</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
- <translation type="unfinished"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
+ <translation>Abilita log di accesso al FS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Avanzate</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Modalità Kiosk (Quest)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Abilita il debug della CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Abilita le asserzioni di debug</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation>Abilita tutti i tipi di controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Disabilita l&apos;applet web</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**L&apos;opzione verrà automaticamente ripristinata alla chiusura di yuzu.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation>Riavvio richiesto</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation>yuzu dev&apos;essere riavviato affinché questa opzione venga applicata.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1285,7 +1320,7 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
<message>
<location filename="../../src/yuzu/configuration/configure_general.cpp" line="69"/>
<source>This reset all settings and remove all per-game configurations. This will not delete game directories, profiles, or input profiles. Proceed?</source>
- <translation>Questo resetta tutte le impostazioni e rimuove tutte le configurazioni per gioco. Questo, non cancellerà le cartelle di gioco, i profili o i profili di input. Vuoi Procedere ?</translation>
+ <translation>Tutte le impostazioni verranno ripristinate e tutte le configurazioni dei giochi verranno rimosse. Le cartelle di gioco, i profili e i profili di input non saranno cancellati. Vuoi procedere?</translation>
</message>
</context>
<context>
@@ -1308,7 +1343,7 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="64"/>
<source>Shader Backend:</source>
- <translation type="unfinished"/>
+ <translation>Backend degli shader:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics.ui" line="92"/>
@@ -1570,37 +1605,47 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Filtro anisotropico:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>Automatico</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Predefinito</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -1673,7 +1718,7 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="242"/>
<source>Invalid</source>
- <translation type="unfinished"/>
+ <translation>Non valido</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="343"/>
@@ -2092,7 +2137,7 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Levetta sinistra</translation>
</message>
@@ -2186,14 +2231,14 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2212,7 +2257,7 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Più</translation>
</message>
@@ -2225,15 +2270,15 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2290,231 +2335,236 @@ Questo bannerà sia il suo nome utente del forum che il suo indirizzo IP.</trans
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Levetta destra</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Cancella</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[non impostato]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Premi il bottone</translation>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
+ <source>Invert button</source>
+ <translation>Inverti pulsante</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
- <source>Invert button</source>
- <translation type="unfinished"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Premi il pulsante</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Inverti assi</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>Imposta soglia</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Scegli un valore compreso tra 0% e 100%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Mappa la levetta analogica</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Dopo aver premuto OK, prima muovi la levetta orizzontalmente, e poi verticalmente.
Per invertire gli assi, prima muovi la levetta verticalmente, e poi orizzontalmente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Zona morta: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Modifica raggio: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Due Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Joycon sinistro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Joycon destro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Portatile</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>Controller GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>Poké Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>Controller NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>Controller SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>Controller N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Avvia / Metti in pausa</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Levetta di Controllo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>Levetta C</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Scuoti!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[in attesa]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Nuovo profilo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Inserisci un nome profilo:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Crea un profilo di Input</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>Il nome profilo dato non è valido!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Impossibile creare il profilo di input &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Elimina un profilo di Input</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Impossibile eliminare il profilo di input &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Carica un profilo di input</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Impossibile caricare il profilo di input &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Salva un profilo di Input</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Impossibile creare il profilo di input &quot;%1&quot;</translation>
</message>
@@ -2769,42 +2819,42 @@ Per invertire gli assi, prima muovi la levetta verticalmente, e poi orizzontalme
<translation>Sviluppatore</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Add-on</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Generale</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Grafica</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Grafiche Avanzate</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Audio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Proprietà</translation>
</message>
@@ -3516,47 +3566,47 @@ Per invertire gli assi, prima muovi la levetta verticalmente, e poi orizzontalme
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Gli script vengono letti seguendo lo stesso formato degli script di TAS-nx.&lt;br/&gt;Per saperne di più, puoi consultare &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;questa pagina&lt;/span&gt;&lt;/a&gt; sul sito di yuzu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>IMPORTANTE: questa funzione è ancora in fase sperimentale.&lt;br/&gt;Gli script NON verranno riprodotti perfettamente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Impostazioni</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>Attiva le funzioni di TASing</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>Cartella degli script</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Percorso</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3966,7 +4016,7 @@ Trascina i punti per cambiare posizione, oppure clicca due volte la cella in tab
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Verifica</translation>
</message>
@@ -4028,7 +4078,7 @@ Trascina i punti per cambiare posizione, oppure clicca due volte la cella in tab
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="186"/>
<source>Show Current Game in your Discord Status</source>
- <translation>Mostra il Gioco Attuale nel tuo Stato di Discord</translation>
+ <translation>Mostra il gioco attuale nel tuo stato di Discord</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="68"/>
@@ -4053,7 +4103,7 @@ Trascina i punti per cambiare posizione, oppure clicca due volte la cella in tab
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Non specificato</translation>
</message>
@@ -4068,17 +4118,36 @@ Trascina i punti per cambiare posizione, oppure clicca due volte la cella in tab
<translation>Il token non è stato verificato. La modifica al token non è stata salvata.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation>Non verificato, clicca su &quot;Verifica&quot; prima di salvare la configurazione</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Verifica in corso...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation>Verificato</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
+ <source>Verification failed</source>
+ <comment>Tooltip</comment>
+ <translation>Verifica fallita</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
<source>Verification failed</source>
<translation>Verifica fallita</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Verifica fallita. Controlla di aver inserito il token correttamente, e che la tua connessione a internet sia funzionante.</translation>
</message>
@@ -4147,12 +4216,12 @@ Trascina i punti per cambiare posizione, oppure clicca due volte la cella in tab
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation>Connessione in corso</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation>Connetti</translation>
</message>
@@ -4160,494 +4229,494 @@ Trascina i punti per cambiare posizione, oppure clicca due volte la cella in tab
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Vengono raccolti dati anonimi&lt;/a&gt; per aiutarci a migliorare yuzu. &lt;br/&gt;&lt;br/&gt;Desideri condividere i tuoi dati di utilizzo con noi?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
- <translation type="unfinished"/>
+ <translation>Rilevata installazione di Vulkan non funzionante</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
- <translation type="unfinished"/>
+ <translation>L&apos;inizializzazione di Vulkan è fallita durante l&apos;avvio.&lt;br&gt;&lt;br&gt;Clicca &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;qui per istruzioni su come risolvere il problema&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Caricamento dell&apos;applet web...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Disabilita l&apos;applet web</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>Il numero di shaders al momento in costruzione</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Velocità corrente dell&apos;emulazione. Valori più alti o più bassi di 100% indicano che l&apos;emulazione sta funzionando più velocemente o lentamente rispetto a una Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Quanti frame al secondo il gioco mostra attualmente. Questo varia da gioco a gioco e da situazione a situazione.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tempo utilizzato per emulare un frame della Switch, non contando i limiti ai frame o il v-sync.
Per un&apos;emulazione alla massima velocità, il valore dev&apos;essere al massimo 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Cancella i file recenti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>&amp;Continua</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Pausa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
- <translation>Avviso Formato di Gioco Obsoleto</translation>
+ <translation>Formato del gioco obsoleto</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Stai usando una cartella con dentro una ROM decostruita come formato per avviare questo gioco, è un formato obsoleto ed è stato sostituito da altri come NCA, NAX, XCI o NSP. Le ROM decostruite non hanno icone, metadata e non supportano gli aggiornamenti. &lt;br&gt;&lt;br&gt;Per una spiegazione sui vari formati di Switch che yuzu supporta, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;controlla la nostra wiki&lt;/a&gt;. Questo messaggio non verrà più mostrato.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Errore nel caricamento della ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>Il formato della ROM non è supportato.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>E&apos; stato riscontrato un errore nell&apos;inizializzazione del core video.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Errore nel caricamento della ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Per favore segui &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;la guida rapida di yuzu&lt;/a&gt; per rifare il dump dei file.&lt;br&gt;Puoi fare riferimento alla wiki di yuzu&lt;/a&gt; o al canale Discord di yuzu&lt;/a&gt; per aiuto.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Si è verificato un errore sconosciuto. Visualizza il log per maggiori dettagli.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Dati di salvataggio</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Dati delle mod</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Errore nell&apos;apertura della cartella %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>La cartella non esiste!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Errore nell&apos;apertura della cache trasferibile degli shader</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Impossibile creare la cartella della cache degli shader per questo titolo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Contenuti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Aggiornamento</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Rimuovi voce</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>Vuoi rimuovere i %1 installati del gioco?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>Rimosso con successo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>Rimosso con successo il gioco base installato</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>Errore durante la rimozione %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Il gioco base non è installato su NAND e non può essere rimosso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>Aggiornamento rimosso on successo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>Non c&apos;è alcun aggiornamento installato per questo gioco.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>Non c&apos;è alcun DLC installato per questo gioco.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Rimossi con successo %1 DLC installati.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Vuoi rimuovere la cache trasferibile degli shader OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Vuoi rimuovere la cache trasferibile degli shader Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Vuoi rimuovere tutte le cache trasferibili degli shader?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>Vuoi rimuovere la configurazione personalizzata del gioco?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Rimuovi file</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Errore nella rimozione della cache trasferibile degli shader</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>Per questo titolo non esiste una cache degli shader.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>La cache trasferibile degli shader è stata rimossa con successo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Impossibile rimuovere la cache trasferibile degli shader.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Errore nella rimozione delle cache trasferibili degli shader</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Le cache trasferibili degli shader sono state rimosse con successo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Impossibile rimuovere la cartella della cache trasferibile degli shader.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Errore nella rimozione della configurazione personalizzata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Non esiste una configurazione personalizzata per questo gioco.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>La configurazione personalizzata del gioco è stata rimossa con successo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Impossibile rimuovere la configurazione personalizzata del gioco.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>Estrazione RomFS fallita!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>C&apos;è stato un errore nella copia dei file del RomFS o l&apos;operazione è stata annullata dall&apos;utente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Completa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Cartelle</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Seleziona la modalità di estrazione della RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Seleziona come vorresti estrarre la RomFS. &lt;br&gt;La modalità Completa copierà tutti i file in una nuova cartella mentre&lt;br&gt;la modalità Cartelle creerà solamente le cartelle e le sottocartelle.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Estrazione RomFS in corso...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Annulla</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Estrazione RomFS riuscita!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>L&apos;operazione è stata completata con successo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Errore nell&apos;apertura di %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Seleziona cartella</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Proprietà</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Le proprietà del gioco non sono potute essere caricate.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Eseguibile Switch (%1);;Tutti i File (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Carica file</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Apri Cartella ROM Estratta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Cartella selezionata non valida</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>La cartella che hai selezionato non contiene un file &quot;main&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>File installabili Switch (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Installa file</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n file rimanente</numerusform><numerusform>%n file rimanenti</numerusform><numerusform>%n file rimanenti</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Installazione del file &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Risultati dell&apos;installazione</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Per evitare possibli conflitti, scoraggiamo gli utenti dall&apos;installare giochi base su NAND.
Per favore, usare questa funzione solo per installare aggiornamenti e DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n file è stato sovrascritto
@@ -4656,418 +4725,398 @@ Per favore, usare questa funzione solo per installare aggiornamenti e DLC.</tran
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Applicazione di sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Archivio di sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Aggiornamento di un&apos;applicazione di sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Pacchetto Firmware (Tipo A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Pacchetto Firmware (Tipo B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Gioco</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Aggiornamento di gioco</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Titolo Delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Seleziona il Tipo di Installazione NCA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Seleziona il tipo del file NCA da installare:
(Nella maggior parte dei casi, il predefinito &apos;Gioco&apos; va bene.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Installazione fallita</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Il tipo che hai selezionato per l&apos;NCA non è valido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>File non trovato</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>File &quot;%1&quot; non trovato</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Account di yuzu non trovato</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Per segnalare la compatibilità di un gioco, devi collegare il tuo account yuzu. &lt;br&gt;&lt;br/&gt;Per collegare il tuo account yuzu, vai su Emulazione &amp;gt;
Configurazione &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Errore aprendo l&apos;URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Impossibile aprire l&apos;URL &quot;% 1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>Vuoi sovrascrivere il file del giocatore 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>Trovata configurazione invalida</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Il controller portatile non può essere utilizzato in modalità docked. Verrà selezionato il controller Pro.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>Errore</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation>L&apos;Amiibo corrente è stato rimosso</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>File Amiibo (%1);; Tutti I File (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Carica Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Errore nell&apos;apertura del file dati Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Impossibile aprire e leggere il file Amiibo &quot;%1&quot;.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Errore nella lettura dei dati del file Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Impossibile leggere tutti i dati dell&apos;Amiibo. E&apos; stato possibile leggere solamente %2 byte di %1.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Errore nel caricamento dei dati dell&apos;Amiibo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Impossibile caricare i dati dell&apos;Amiibo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Cattura Screenshot</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>Immagine PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Avvia</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>Interrompi r&amp;egistrazione</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>R&amp;egistra</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Velocità: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Velocità: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Gioco: %1 FPS (Sbloccati)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Gioco: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Frame: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMALE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU ALTA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU ESTREMA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>ERRORE GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation>PORTATILE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>NEAREST</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>BILINEARE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>BICUBICO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>GAUSSIANO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>NO AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>Il gioco che stai provando a caricare richiede ulteriori file che devono essere estratti dalla tua Switch prima di poter giocare. &lt;br/&gt;&lt;br/&gt;Per maggiori informazioni sull&apos;estrazione di questi file, visualizza la seguente pagina della wiki: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Estrazione degli archivi di sistema e dei font condivisi da una console Switch&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Vuoi uscire e tornare alla lista dei giochi? Proseguendo l&apos;emulazione si potrebbero verificare arresti anomali, salvataggi corrotti o altri bug.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>yuzu non ha potuto individuare un archivio di sistema della Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>yuzu non ha potuto individuare un archivio di sistema della Switch: %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Archivio di sistema non trovato</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Archivio di sistema mancante</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu non ha potuto individuare i font condivisi della Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Font condivisi non trovati</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Font condivisi mancanti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Errore Fatale</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu ha riscontrato un errore fatale, visualizza il log per maggiori dettagli. Per maggiori informazioni su come accedere al log, visualizza la seguente pagina: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Come caricare il file di log&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Vuoi uscire e tornare alla lista dei giochi? Proseguendo l&apos;emulazione si potrebbero verificare arresti anomali, salvataggi corrotti o altri bug.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Errore Fatale riscontrato</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
- <translation>Conferma Riderivazione Chiave</translation>
+ <translation>Conferma ri-derivazione chiavi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5084,37 +5133,37 @@ e facoltativamente fai dei backup.
Questo eliminerà i tuoi file di chiavi autogenerati e ri-avvierà il processo di derivazione delle chiavi.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>Fusi mancanti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation> - BOOT0 mancante</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - BCPKG2-1-Normal-Main mancante</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation>- PRODINFO mancante</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>Componenti di derivazione mancanti</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5123,39 +5172,39 @@ Questa operazione potrebbe durare fino a un minuto in
base alle prestazioni del tuo sistema.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Derivazione chiavi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Seleziona Target dell&apos;Estrazione del RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Seleziona quale RomFS vorresti estrarre.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Sei sicuro di voler chiudere yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Sei sicuro di voler arrestare l&apos;emulazione? Tutti i progressi non salvati verranno perduti.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5284,7 +5333,7 @@ Desideri uscire comunque?</translation>
<message>
<location filename="../../src/yuzu/game_list.cpp" line="553"/>
<source>Dump RomFS to SDMC</source>
- <translation type="unfinished"/>
+ <translation>Estrai RomFS su SDMC</translation>
</message>
<message>
<location filename="../../src/yuzu/game_list.cpp" line="554"/>
@@ -5416,8 +5465,8 @@ a causa della presenza di glitch anche utilizzando degli espedienti.</translatio
<location filename="../../src/yuzu/game_list_p.h" line="153"/>
<source>Game is completely unplayable due to major graphical or audio glitches. Unable to progress past the Start
Screen.</source>
- <translation>Il gioco è completamente ingiocabile a causa di errori gravi audio o video. È impossibile proseguire oltre la Schermata
-Iniziale.</translation>
+ <translation>Il gioco è del tutto ingiocabile a causa di considerevoli glitch audio o video.
+È impossibile proseguire oltre la schermata iniziale.</translation>
</message>
<message>
<location filename="../../src/yuzu/game_list_p.h" line="154"/>
@@ -5453,7 +5502,7 @@ Iniziale.</translation>
<message numerus="yes">
<location filename="../../src/yuzu/game_list.cpp" line="86"/>
<source>%1 of %n result(s)</source>
- <translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
+ <translation><numerusform>%1 di %n risultato</numerusform><numerusform>%1 di %n risultati</numerusform><numerusform>%1 di %n risultati</numerusform></translation>
</message>
<message>
<location filename="../../src/yuzu/game_list.cpp" line="776"/>
@@ -5537,12 +5586,12 @@ Iniziale.</translation>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>Errore</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation>Impossibile annunciare la stanza alla lobby pubblica. Per ospitare una stanza pubblicamente, devi avere un account yuzu valido configurato in Emulazione -&gt; Configura -&gt; Web. Se non desideri pubblicare una stanza nella lobby pubblica, seleziona Non in lista.
@@ -5552,11 +5601,12 @@ Messaggio di debug:</translation>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5578,112 +5628,111 @@ Messaggio di debug:</translation>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation>Finestra principale</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Cattura Screenshot</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
- <translation type="unfinished"/>
+ <translation>Esci da yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
- <translation>Schermo Intero</translation>
+ <translation>Schermo intero</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Carica file</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation>Carica/Rimuovi Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
- <translation type="unfinished"/>
+ <translation>Riavvia l&apos;emulazione</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation>Arresta l&apos;emulazione</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5798,42 +5847,42 @@ Messaggio di debug:</translation>
<translation>Aggiorna lobby</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation>Password richiesta per entrare</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation>Password:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation>Nome stanza</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation>Gioco preferito</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation>Host</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Giocatori</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation>Aggiornamento in corso</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation>Aggiorna lista</translation>
</message>
@@ -6160,7 +6209,7 @@ Messaggio di debug:</translation>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Connesso</translation>
</message>
@@ -6183,7 +6232,7 @@ Debug Message: </source>
Messaggio di debug:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation>Nuovi messaggi ricevuti</translation>
</message>
@@ -6288,22 +6337,39 @@ They may have left the room.</source>
Potrebbe aver abbandonato la stanza.</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation>Esci dalla stanza</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation>Stai per chiudere la stanza. Ogni connessione di rete verrà chiusa.</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation>Disconnetti</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation>Stai per uscire dalla stanza. Ogni connessione di rete verrà chiusa.</translation>
</message>
@@ -6311,7 +6377,7 @@ Potrebbe aver abbandonato la stanza.</translation>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>Errore</translation>
</message>
@@ -6370,7 +6436,7 @@ p, li { white-space: pre-wrap; }
<translation>%1 sta giocando a %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation>Non in gioco</translation>
</message>
@@ -6425,7 +6491,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[non impostato]</translation>
</message>
@@ -6440,10 +6506,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Asse %1%2</translation>
</message>
@@ -6457,9 +6523,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[sconosciuto]</translation>
</message>
@@ -6624,15 +6690,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation type="unfinished"/>
</message>
@@ -6640,35 +6706,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
- <translation type="unfinished"/>
+ <translation>%1%2Asse %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
- <translation type="unfinished"/>
+ <translation>%1%2Asse %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
- <translation type="unfinished"/>
+ <translation>%1%2Pulsante %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[inutilizzato]</translation>
</message>
@@ -6709,7 +6775,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation type="unfinished"/>
</message>
diff --git a/dist/languages/ja_JP.ts b/dist/languages/ja_JP.ts
index 3c66d5da2..b621cdbf2 100644
--- a/dist/languages/ja_JP.ts
+++ b/dist/languages/ja_JP.ts
@@ -82,7 +82,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="14"/>
<source>Room Window</source>
- <translation type="unfinished"/>
+ <translation>ルームウインドウ</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="40"/>
@@ -95,78 +95,78 @@ p, li { white-space: pre-wrap; }
<translation>メッセージを送る</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation>メンバー</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation>%1 が参加しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation>%1 が退出しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation>%1 はキックされました</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation>%1 はBanされました</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation>%1 はBan解除されました</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation>プロフィールを見る</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation>ブロックすると、そのプレイヤーからのチャットメッセージが届かなくなります。&lt;br&gt;&lt;br&gt;%1を本当にブロックしますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation>キック</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation>Ban</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation>プレイヤーをキック</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation>%1 を&lt;b&gt;キック&lt;/b&gt;しますがよろしいですか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation>プレイヤーをBan</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -180,7 +180,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="14"/>
<source>Room Window</source>
- <translation type="unfinished"/>
+ <translation>ルームウインドウ</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="27"/>
@@ -213,7 +213,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="100"/>
<source>%1 (%2/%3 members) - connected</source>
- <translation type="unfinished"/>
+ <translation>%1 (%2/%3 メンバー) - 接続済み</translation>
</message>
</context>
<context>
@@ -380,7 +380,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="14"/>
<source>Configure Infrared Camera</source>
- <translation type="unfinished"/>
+ <translation>赤外線カメラを設定</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="26"/>
@@ -771,200 +771,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation>デバッガ―</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>GDBスタブの有効化</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>ポート:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>ログ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>グローバルログフィルター</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>コンソールにログを表示</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>ログ出力フォルダを開く</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>チェックすると、ログの最大サイズが100MBから1GBに増加します。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>拡張ログの有効化**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>引数</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>グラフィック</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>チェックすると、 グラフィックAPIはより遅いデバッグモードになります。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>グラフィックデバッグの有効化</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>チェックすると、Nsight Aftermathのクラッシュダンプが有効になります</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Nsight Aftermathの有効化</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation>チェックすると、ディスクシェーダーキャッシュまたはゲームからオリジナルのアセンブラーシェーダーをすべてダンプします</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation>ゲームシェーダーをダンプ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation>チェックすると、GPUのすべてのマクロプログラムをダンプします</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation>Maxwellマクロをダンプ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>チェックすると、マクロのJust In Timeコンパイラが無効になります。有効にすると、ゲームの動作が遅くなります。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Macro JITを無効化</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>チェックすると、コンパイルしたパイプラインキャッシュの統計情報をロギングします</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>シェーダフィードバックの有効j化</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>チェックすると、ループロジックを変更せずにシェーダーを実行します。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>ループ安全性チェックの無効化</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>デバッグ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
- <source>Enable FS Access Log</source>
- <translation>FSアクセスログの有効化</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>詳細なレポートサービスの有効化**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
- <translation type="unfinished"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
+ <translation>FSアクセスログの有効化</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>これを有効にすると、最新のオーディオコマンドリストがコンソールに出力されます。オーディオレンダラーを使用するゲームにのみ影響します。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>詳細なレポートサービスの有効化**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation>クラッシュ時にミニダンプを生成</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>高度</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Kiosk (Quest) Mode</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>CPUデバッグの有効化</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>デバッグアサートの有効化</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>自動スタブの有効化**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation>すべてのコントローラタイプを有効にする</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Webアプレットの無効化</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>** yuzuを終了したときに自動的にリセットされます。</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation>再起動が必要</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation>この設定を適用するには yuzu を再起動する必要があります.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1583,37 +1618,47 @@ This would ban both their forum username and their IP address.</source>
<translation>高速なGPUタイミングを有効化(ハック)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation>悲観的なバッファフラッシュを有効にします. このオプションは, 変更されていないバッファを強制的にフラッシュさせるので, パフォーマンスが低下する可能性があります.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation>悲観的なバッファフラッシュを使用 (ハック)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>異方性フィルタリング:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>自動</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>デフォルト</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2013,7 +2058,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2623"/>
<source>Infrared Camera</source>
- <translation type="unfinished"/>
+ <translation>赤外線カメラ</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2640"/>
@@ -2105,7 +2150,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Lスティック</translation>
</message>
@@ -2199,14 +2244,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2225,7 +2270,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>+</translation>
</message>
@@ -2238,15 +2283,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2303,231 +2348,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Rスティック</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>クリア</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[未設定]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation type="unfinished"/>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>ボタンを反転</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>軸を反転</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>しきい値を設定</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>0%から100%の間の値を選択してください</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation>ジャイロのしきい値を設定</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>アナログスティックをマップ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>OKを押した後、スティックを水平方向に動かし、次に垂直方向に動かしてください。
軸を反転させる場合、 最初に垂直方向に動かし、次に水平方向に動かしてください。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>デッドゾーン:%1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>変更範囲:%1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Proコントローラ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Joy-Con(L/R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Joy-Con(L)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Joy-Con(R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>携帯モード</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>ゲームキューブコントローラ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>モンスターボールプラス</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>ファミコン・コントローラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>スーパーファミコン・コントローラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>ニンテンドウ64・コントローラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>メガドライブ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>スタート/ ポーズ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>Cスティック</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>振ってください</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[待機中]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>新規プロファイル</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>プロファイル名を入力:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>入力プロファイルを作成</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>プロファイル名が無効です!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>入力プロファイル &quot;%1&quot; の作成に失敗しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>入力プロファイルを削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>入力プロファイル &quot;%1&quot; の削除に失敗しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>入力プロファイルをロード</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>入力プロファイル &quot;%1&quot; のロードに失敗しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>入力プロファイルをセーブ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>入力プロファイル &quot;%1&quot; のセーブに失敗しました</translation>
</message>
@@ -2565,7 +2615,7 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="23"/>
<source>UDP Calibration:</source>
- <translation type="unfinished"/>
+ <translation>UDP補正:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="30"/>
@@ -2782,42 +2832,42 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation>開発元</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>アドオン</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>全般</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>システム</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>グラフィック</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>高度なグラフィック</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>サウンド</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>プロパティ</translation>
</message>
@@ -3529,47 +3579,47 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;TAS-nxスクリプトと同じフォーマットでスクリプトからコントローラ入力を読み込みます。&lt;br/&gt;より詳細な説明は、yuzuホームページの&lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;ヘルプ&lt;/span&gt;&lt;/a&gt;を参照してください。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>どのホットキーで再生/録音を制御するかは、ホットキーの設定(設定>一般>ホットキー)を参照してください。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>警告:実験的な機能です。&lt;br/&gt;現状では完全な再生や同期はできません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>設定</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>TAS機能の有効化</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>スクリプトを繰り返し実行</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>ロード中は実行を一時停止</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>スクリプトディレクトリ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>パス</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3979,7 +4029,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>検証</translation>
</message>
@@ -4066,7 +4116,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>未設定</translation>
</message>
@@ -4081,17 +4131,36 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>トークンは検証されていません。トークンの変更はまだ保存されていません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>検証中...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>検証に失敗</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>検証に失敗</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>検証に失敗しました。トークンが正しく入力されていること、およびインターネット接続が機能していることを確認してください。</translation>
</message>
@@ -4114,7 +4183,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="14"/>
<source>Direct Connect</source>
- <translation type="unfinished"/>
+ <translation>ダイレクト接続</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="33"/>
@@ -4144,7 +4213,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="100"/>
<source>Nickname</source>
- <translation type="unfinished"/>
+ <translation>ニックネーム</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="114"/>
@@ -4160,12 +4229,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation>接続中</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation>接続</translation>
</message>
@@ -4173,913 +4242,893 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>yuzuを改善するための&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;匿名データが収集されました&lt;/a&gt;。&lt;br/&gt;&lt;br/&gt;統計情報データを共有しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>テレメトリ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation>壊れたVulkanのインストールが検出されました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>ブート時にVulkanの初期化に失敗しました。&lt;br&gt;&lt;br&gt;この問題を解決するための手順は&lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;こちら&lt;/a&gt;。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Webアプレットをロード中...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Webアプレットの無効化</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Webアプレットを無効にすると、未定義の動作になる可能性があるため、スーパーマリオ3Dオールスターズでのみ使用するようにしてください。本当にWebアプレットを無効化しますか?
(デバッグ設定で再度有効にすることができます)。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>ビルド中のシェーダー数</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>現在選択されている解像度の倍率。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>現在のエミュレーション速度。値が100%より高いか低い場合、エミュレーション速度がSwitchより速いか遅いことを示します。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>ゲームが現在表示している1秒あたりのフレーム数。これはゲームごと、シーンごとに異なります。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Switchフレームをエミュレートするのにかかる時間で、フレームリミットやV-Syncは含まれません。フルスピードエミュレーションの場合、最大で16.67ミリ秒になります。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>最近のファイルをクリア(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>再開(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>中断(&amp;P)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>yuzuはゲームを起動しています</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>古いゲームフォーマットの警告</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>このゲームでは、分解されたROMディレクトリフォーマットを使用しています。これは、NCA、NAX、XCI、またはNSPなどに取って代わられた古いフォーマットです。分解されたROMディレクトリには、アイコン、メタデータ、およびアップデートサポートがありません。&lt;br&gt;&lt;br&gt;yuzuがサポートするSwitchフォーマットの説明については、&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;wikiをチェックしてください&lt;/a&gt;。このメッセージは二度と表示されません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>ROMロード中にエラーが発生しました!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>このROMフォーマットはサポートされていません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>ビデオコア初期化中にエラーが発生しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzuは、ビデオコアの実行中にエラーが発生しました。これは通常、内蔵GPUも含め、古いGPUドライバが原因です。詳しくはログをご覧ください。ログへのアクセス方法については、以下のページをご覧ください:&lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;ログファイルのアップロード方法について&lt;/a&gt;。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>ROMのロード中にエラー! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzuクイックスタートガイド&lt;/a&gt;を参照してファイルを再ダンプしてください。&lt;br&gt;またはyuzu wiki及び&lt;/a&gt;yuzu Discord&lt;/a&gt;を参照するとよいでしょう。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>不明なエラーが発生しました。詳細はログを確認して下さい。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>データのセーブ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Modデータ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>”%1”フォルダを開けませんでした</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>フォルダが存在しません!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>シェーダキャッシュを開けませんでした</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>このタイトル用のシェーダキャッシュディレクトリの作成に失敗しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>コンテンツ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>アップデート</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>エントリ削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>インストールされているゲーム%1を削除しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>削除しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>インストールされたゲームを正常に削除しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>%1削除エラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>ゲームはNANDにインストールされていないため、削除できません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>インストールされたアップデートを正常に削除しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>このタイトルのアップデートはインストールされていません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>このタイトルにはDLCがインストールされていません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>%1にインストールされたDLCを正常に削除しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>転送可能なOpenGLシェーダキャッシュを削除しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>転送可能なVulkanシェーダキャッシュを削除しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>転送可能なすべてのシェーダキャッシュを削除しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>このタイトルのカスタム設定を削除しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>ファイル削除</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>転送可能なシェーダーキャッシュの削除エラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>このタイトル用のシェーダキャッシュは存在しません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>転送可能なシェーダーキャッシュが正常に削除されました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>転送可能なシェーダーキャッシュを削除できませんでした。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>転送可能なシェーダキャッシュの削除エラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>転送可能なシェーダキャッシュを正常に削除しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>転送可能なシェーダキャッシュディレクトリの削除に失敗しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>カスタム設定の削除エラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>このタイトルのカスタム設定は存在しません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>カスタム設定を正常に削除しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>カスタム設定の削除に失敗しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFSの解析に失敗しました!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>RomFSファイルをコピー中にエラーが発生したか、ユーザー操作によりキャンセルされました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>フル</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>スケルトン</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>RomFSダンプモードの選択</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>RomFSのダンプ方法を選択してください。&lt;br&gt;”完全”はすべてのファイルが新しいディレクトリにコピーされます。&lt;br&gt;”スケルトン”はディレクトリ構造を作成するだけです。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>%1 に RomFS を展開するための十分な空き領域がありません。Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root で、空き容量を確保するか、別のダンプディレクトリを選択してください。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>RomFSを解析中...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>キャンセル</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS解析成功!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>操作は成功しました。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>”%1”を開けませんでした</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>ディレクトリの選択</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>プロパティ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>ゲームプロパティをロード出来ませんでした。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch実行ファイル (%1);;すべてのファイル (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>ファイルのロード</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>展開されているROMディレクトリを開く</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>無効なディレクトリが選択されました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>選択されたディレクトリに”main”ファイルが見つかりませんでした。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>インストール可能なスイッチファイル (*.nca *.nsp *.xci);;任天堂コンテンツアーカイブ (*.nca);;任天堂サブミッションパッケージ (*.nsp);;NXカートリッジイメージ (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>ファイルのインストール</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>残り %n ファイル</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>&quot;%1&quot;ファイルをインストールしています・・・</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>インストール結果</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>競合を避けるため、NANDにゲーム本体をインストールすることはお勧めしません。
この機能は、アップデートやDLCのインストールにのみ使用してください。</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n ファイルが新たにインストールされました
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n ファイルが上書きされました
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n ファイルのインストールに失敗しました
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>システムアプリケーション</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>システムアーカイブ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>システムアプリケーションアップデート</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>ファームウェアパッケージ(Type A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>ファームウェアパッケージ(Type B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>ゲーム</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>ゲームアップデート</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>ゲームDLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>差分タイトル</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>NCAインストール種別を選択・・・</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>インストールするNCAタイトル種別を選択して下さい:
(ほとんどの場合、デフォルトの”ゲーム”で問題ありません。)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>インストール失敗</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>選択されたNCAのタイトル種別が無効です。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>ファイルが存在しません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>ファイル”%1”が存在しません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>yuzuアカウントが存在しません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>ゲームの互換性テストケースを送信するには、yuzuアカウントをリンクする必要があります。&lt;br&gt;&lt;br/&gt;yuzuアカウントをリンクするには、エミュレーション > 設定 > Web から行います。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>URLオープンエラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>URL&quot;%1&quot;を開けません。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation> TAS 記録中</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>プレイヤー1のファイルを上書きしますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>無効な設定を検出しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>携帯コントローラはドックモードで使用できないため、Proコントローラが選択されます。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>エラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation>現在のゲームはamiiboを要求しません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
- <translation type="unfinished"/>
+ <translation>現在の amiibo は削除されました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>amiiboファイル (%1);;すべてのファイル (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>amiiboのロード</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>amiiboデータファイルを開けませんでした</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>amiiboデータファイル”%1”を読み込めませんでした。</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>amiiboデータファイルを読み込み中にエラーが発生した</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>amiiboデータを完全には読み取ることができませんでした。%1バイトを読み込もうとしましたが、%2バイトしか読み取れませんでした。</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>amiiboデータ読み込み中にエラーが発生しました</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>amiiboデータをロードできませんでした。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>スクリーンショットのキャプチャ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>PNG画像 (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS 状態: 実行中 %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>TAS 状態: 記録中 %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAS 状態: アイドル %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>TAS 状態: 無効</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>実行停止(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>実行(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>記録停止(&amp;R)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>記録(&amp;R)</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>構築中: %n シェーダー</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>拡大率: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>速度:%1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>速度:%1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Game: %1 FPS(制限解除)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>ゲーム:%1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>フレーム:%1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU HIGH</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU EXTREME</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>GPU ERROR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation>DOCKED</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation>HANDHELD</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>NEAREST</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>BILINEAR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>BICUBIC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>GAUSSIAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>NO AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>ロードしようとしているゲームはプレイする前に、追加のファイルを必要とします。それはSwitchからダンプする必要があります。&lt;br/&gt;&lt;br/&gt;これらのファイルのダンプの詳細については、次のWikiページを参照してください:&lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;スイッチコンソールからのシステムアーカイブと共有フォントをダンプする&lt;/a&gt;。&lt;br/&gt;&lt;br/&gt;ゲームリストに戻りますか?エミュレーションを続けると、クラッシュ、保存データの破損、またはその他のバグが発生する可能性があります。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>yuzuはSwitchのシステムアーカイブ &quot;%1&quot; を見つけられませんでした。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>yuzuはSwitchのシステムアーカイブ &quot;%1&quot; &quot;%2&quot; を見つけられませんでした。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>システムアーカイブが見つかりません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>システムアーカイブが見つかりません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzuはSwitchの共有フォント &quot;%1&quot; を見つけられませんでした。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>共有フォントが存在しません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>共有フォントが存在しません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>致命的なエラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzuが致命的なエラーを検出しました。詳細については、ログを参照してください。ログへのアクセスの詳細については、次のページを参照してください。&lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;ログファイルをアップロードする方法&lt;/a&gt;。&lt;br/&gt;&lt;br/&gt;ゲームリストに戻りますか?エミュレーションを続けると、クラッシュ、保存データの破損、またはその他のバグが発生する可能性があります。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>致命的なエラー発生</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>キーの再取得確認</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5096,37 +5145,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
実行すると、自動生成された鍵ファイルが削除され、鍵生成モジュールが再実行されます。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>ヒューズがありません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation> - BOOT0がありません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - BCPKG2-1-Normal-Mainがありません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation> - PRODINFOがありません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>派生コンポーネントがありません</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>暗号化キーがありません。&lt;br&gt;キー、ファームウェア、ゲームを取得するには&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu クイックスタートガイド&lt;/a&gt;を参照ください。&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5135,39 +5184,39 @@ on your system&apos;s performance.</source>
1分以上かかります。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>派生キー</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>RomFSダンプターゲットの選択</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>ダンプしたいRomFSを選択して下さい。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>yuzuを終了しますか?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>エミュレーションを停止しますか?セーブされていない進行状況は失われます。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5493,7 +5542,7 @@ Screen.</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="61"/>
<source>Max Players</source>
- <translation type="unfinished"/>
+ <translation>最大プレイヤー数</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="91"/>
@@ -5538,18 +5587,18 @@ Screen.</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="197"/>
<source>Host Room</source>
- <translation type="unfinished"/>
+ <translation>ホストルーム</translation>
</message>
</context>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>エラー</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation>公開ロビーへの部屋のアナウンスに失敗しました。部屋を公開するためには、Emulation -&gt; Configure -&gt; Web で有効なyuzuアカウントが設定されている必要があります。もし、部屋を公開ロビーに公開したくないのであれば、代わりに非公開を選択してください。
@@ -5559,11 +5608,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation>音声ミュート/解除</translation>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5585,114 +5635,113 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation>メイン画面</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation>音量を下げる</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation>音量を上げる</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>スクリーンショットを撮る</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation>アダプティングフィルターの変更</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation>ドックモードを変更</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation>GPU精度を変更</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation>エミュレーションの一時停止/再開</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation>フルスクリーンをやめる</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation>yuzuを終了</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>フルスクリーン</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>ファイルのロード</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation>読み込み/解除 Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation>エミュレーションをリスタート</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation>エミュレーションをやめる</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation>TAS 記録</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation>TAS リセット</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation>TAS 開始/停止</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
- <translation type="unfinished"/>
+ <translation>フィルタバー切り替え</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
- <translation type="unfinished"/>
+ <translation>フレームレート制限切り替え</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
- <translation type="unfinished"/>
+ <translation>ステータスバー切り替え</translation>
</message>
</context>
<context>
@@ -5771,13 +5820,13 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="14"/>
<source>Public Room Browser</source>
- <translation type="unfinished"/>
+ <translation>公開ルームブラウザ</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="32"/>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="39"/>
<source>Nickname</source>
- <translation type="unfinished"/>
+ <translation>ニックネーム</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="59"/>
@@ -5805,42 +5854,42 @@ Debug Message: </source>
<translation>ロビー更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation>参加にはパスワードが必要です。</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation>パスワード:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation>ルーム名</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation>ホスト</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>プレイヤー</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation>更新中</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation>リスト更新</translation>
</message>
@@ -6035,7 +6084,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/main.ui" line="307"/>
<source>Load/Remove &amp;Amiibo...</source>
- <translation type="unfinished"/>
+ <translation>&amp;Amiibo をロード/削除...</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="315"/>
@@ -6070,7 +6119,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/main.ui" line="351"/>
<source>&amp;Configure TAS...</source>
- <translation>TASを設定... (%C)</translation>
+ <translation>TASを設定... (&amp;C)</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="359"/>
@@ -6137,7 +6186,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="83"/>
<source>Forum Username</source>
- <translation type="unfinished"/>
+ <translation>フォーラムのユーザ名</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="88"/>
@@ -6167,7 +6216,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>接続の状態</translation>
</message>
@@ -6175,7 +6224,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="99"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="128"/>
<source>Not Connected</source>
- <translation type="unfinished"/>
+ <translation>未接続</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="181"/>
@@ -6190,7 +6239,7 @@ Debug Message: </source>
デバッグメッセージ:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation>新たなメッセージを受信しました</translation>
</message>
@@ -6225,7 +6274,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="20"/>
<source>You must choose a Preferred Game to host a room. If you do not have any games in your game list yet, add a game folder by clicking on the plus icon in the game list.</source>
- <translation type="unfinished"/>
+ <translation>ルームをホスティングするには, 優先ゲームを選択する必要があります. リストにまだゲームがない場合は, リストのプラスアイコンをクリックしてゲームフォルダを追加してください.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="24"/>
@@ -6295,22 +6344,41 @@ They may have left the room.</source>
退室した可能性があります。</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation>ネットワークインタフェースが選択されていません.
+設定 -&gt; システム -&gt; ネットワーク で使用するネットワークを選択してください.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation>ゲーム進行中</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation>ゲーム進行中にルームに参加することはお勧めしません. ルーム機能が正しく動作しない原因になります.
+とにかく実行しますか?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation>ルームを離れる</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation>部屋を閉じようとしています。ネットワーク接続がすべて終了します。</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation>切断</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation>部屋を退出しようとしています。ネットワーク接続はすべて終了します。</translation>
</message>
@@ -6318,7 +6386,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>エラー</translation>
</message>
@@ -6377,7 +6445,7 @@ p, li { white-space: pre-wrap; }
<translation>%1は%2をプレイ中です</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation type="unfinished"/>
</message>
@@ -6432,7 +6500,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[未設定]</translation>
</message>
@@ -6447,10 +6515,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>軸 %1%2</translation>
</message>
@@ -6464,9 +6532,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[不明]</translation>
</message>
@@ -6631,15 +6699,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[無効]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation type="unfinished"/>
</message>
@@ -6647,35 +6715,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2ボタン %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[未使用]</translation>
</message>
@@ -6693,7 +6761,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="108"/>
<source>Wheel</source>
<comment>Indicates the mouse wheel</comment>
- <translation type="unfinished"/>
+ <translation>ホイール</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="110"/>
@@ -6716,7 +6784,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/languages/ko_KR.ts b/dist/languages/ko_KR.ts
index 9dcae2b88..4d3167feb 100644
--- a/dist/languages/ko_KR.ts
+++ b/dist/languages/ko_KR.ts
@@ -36,7 +36,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="130"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;웹사이트&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;소스 코드&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;기여자&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;라이센스&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="146"/>
@@ -82,95 +82,95 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="14"/>
<source>Room Window</source>
- <translation type="unfinished"/>
+ <translation>방의 창</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="40"/>
<source>Send Chat Message</source>
- <translation type="unfinished"/>
+ <translation>채팅 메시지 보내기</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="47"/>
<source>Send Message</source>
- <translation type="unfinished"/>
+ <translation>메시지 보내기</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
- <translation type="unfinished"/>
+ <translation>회원</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
- <translation type="unfinished"/>
+ <translation>%1이(가) 참여하였습니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
- <translation type="unfinished"/>
+ <translation>%1이(가) 떠났습니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
- <translation type="unfinished"/>
+ <translation>%1이(가) 추방되었습니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
- <translation type="unfinished"/>
+ <translation>%1이(가) 차단되었습니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
- <translation type="unfinished"/>
+ <translation>%1이(가) 차단 해제되었습니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
- <translation type="unfinished"/>
+ <translation>프로필 보기</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
- <translation type="unfinished"/>
+ <translation>차단된 플레이어</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
- <translation type="unfinished"/>
+ <translation>플레이어를 차단하면 더 이상 채팅 메시지를 받을 수 없습니다.&lt;br&gt;&lt;br&gt;%1을(를) 차단하겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
- <translation type="unfinished"/>
+ <translation>추방</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
- <translation type="unfinished"/>
+ <translation>차단</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
- <translation type="unfinished"/>
+ <translation>추방된 플레이어</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
- <translation type="unfinished"/>
+ <translation>%1을(를) &lt;b&gt;추방&lt;/b&gt;하겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
- <translation type="unfinished"/>
+ <translation>차단된 플레이어</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
- <translation type="unfinished"/>
+ <translation>%1을(를) &lt;b&gt;추방&lt;/b&gt;하겠습니까? 이렇게 하면 포럼 사용자 이름과 IP 주소가 모두 금지됩니다.</translation>
</message>
</context>
<context>
@@ -178,22 +178,22 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="14"/>
<source>Room Window</source>
- <translation type="unfinished"/>
+ <translation>방의 창</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="27"/>
<source>Room Description</source>
- <translation type="unfinished"/>
+ <translation>방 설명</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="47"/>
<source>Moderation...</source>
- <translation type="unfinished"/>
+ <translation>조정...</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="57"/>
<source>Leave Room</source>
- <translation type="unfinished"/>
+ <translation>방 나가기</translation>
</message>
</context>
<context>
@@ -206,12 +206,12 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="87"/>
<source>Disconnected</source>
- <translation type="unfinished"/>
+ <translation>연결 끊김</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="100"/>
<source>%1 (%2/%3 members) - connected</source>
- <translation type="unfinished"/>
+ <translation>%1 (%2/%3 회원) - 연결됨</translation>
</message>
</context>
<context>
@@ -339,7 +339,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_audio.ui" line="42"/>
<source>Output Device</source>
- <translation type="unfinished"/>
+ <translation>출력 장치</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_audio.ui" line="56"/>
@@ -378,37 +378,37 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="14"/>
<source>Configure Infrared Camera</source>
- <translation type="unfinished"/>
+ <translation>적외선 카메라 구성</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="26"/>
<source>Select where the image of the emulated camera comes from. It may be a virtual camera or a real camera.</source>
- <translation type="unfinished"/>
+ <translation>에뮬레이트된 카메라의 이미지 출처를 선택합니다. 가상 카메라일 수도 있고 실제 카메라일 수도 있습니다.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="52"/>
<source>Camera Image Source:</source>
- <translation type="unfinished"/>
+ <translation>카메라 이미지 출처:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="71"/>
<source>Input device:</source>
- <translation type="unfinished"/>
+ <translation>입력 장치:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="96"/>
<source>Preview</source>
- <translation type="unfinished"/>
+ <translation>미리보기</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="108"/>
<source>Resolution: 320*240</source>
- <translation type="unfinished"/>
+ <translation>해상도: 320*240</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="115"/>
<source>Click to preview</source>
- <translation type="unfinished"/>
+ <translation>클릭하여 미리보기</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="140"/>
@@ -768,200 +768,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation>디버거</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>GDB Stub 활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>포트:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>로깅</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>전역 로그 필터</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>콘솔에 로그 표시</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>로그 경로 열기</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>이 옵션을 활성화 시, 로그 파일의 최대 용량이 100MB에서 1GB로 증가합니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>확장된 로깅 활성화**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>홈브류</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>실행인수</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>그래픽</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>이 옵션을 활성화 시, 그래픽 API가 디버깅 모드로 진입하여 속도가 느려집니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>그래픽 디버깅 활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>선택하면 Nsight Aftermath 크래시 덤프가 활성화됩니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Nsight Aftermath 활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation>선택하면 디스크 셰이더 캐시 또는 게임에서 찾은 모든 원본 어셈블러 셰이더를 덤프합니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation>게임 셰이더 덤프</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation>체크하면 GPU의 모든 매크로 프로그램을 덤프합니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation>Maxwell 매크로 덤프</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>이 옵션에 체크할 시, 매크로 JIT 컴파일러를 비활성화 합니다. 게임 속도가 느려지니 유의하십시오.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Macro JIT 비활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>선택하면 yuzu는 컴파일된 파이프라인 캐시에 대한 통계를 기록합니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>셰이더 피드백 활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>체크 시 루프 로직 변경 없이 셰이더 실행</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>루프 안전 검사 비활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>디버깅</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>자세한 리포팅 서비스 활성화**</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
<source>Enable FS Access Log</source>
<translation>FS 액세스 로그 활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
- <translation type="unfinished"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
+ <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
+ <translation>이 옵션을 활성화하면 가장 최근에 생성된 오디오 명령어 목록을 콘솔에 출력할 수 있습니다. 오디오 렌더러를 사용하는 게임에만 영향을 줍니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
- <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
- <translation type="unfinished"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
+ <translation>콘솔에 오디오 명령어 덤프</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>자세한 리포팅 서비스 활성화**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation>충돌후 미니덤프 생성</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>고급</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Kiosk (Quest) 모드</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>CPU 디버깅 활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>디버그 에러 검출 활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>자동 스텁 활성화**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation>모든 컨트롤러 유형 활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>웹 애플릿 비활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Yuzu가 종료되면 자동으로 재설정됩니다.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation>재시작 필요</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation>이 설정을 적용하려면 yuzu를 다시 시작해야 합니다.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation>웹 애플릿이 컴파일되지 않음</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation>MiniDump 생성이 컴파일되지 않음</translation>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1557,7 +1592,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="78"/>
<source>Use VSync</source>
- <translation type="unfinished"/>
+ <translation>수직 동기화 사용</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="85"/>
@@ -1580,37 +1615,47 @@ This would ban both their forum username and their IP address.</source>
<translation>빠른 GPU 시간 사용(Hack)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation>비관적 버퍼 플러시를 활성화합니다. 이 옵션은 수정되지 않은 버퍼를 강제로 비우므로 성능이 저하될 수 있습니다.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation>비관적 버퍼 플러시 사용(Hack)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>비등방성 필터링:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>자동</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>기본값</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2010,7 +2055,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2623"/>
<source>Infrared Camera</source>
- <translation type="unfinished"/>
+ <translation>적외선 카메라</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2640"/>
@@ -2102,7 +2147,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>L 스틱</translation>
</message>
@@ -2196,14 +2241,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2222,7 +2267,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>+</translation>
</message>
@@ -2235,15 +2280,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2300,231 +2345,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>R 스틱</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>초기화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[설정 안 됨]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>토글 버튼</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>버튼 반전</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>토글 버튼</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>축 뒤집기</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>임계값 설정</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>0%에서 100% 안의 값을 고르세요</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation>axis 토글</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation>자이로 임계값 설정</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>아날로그 스틱 맵핑</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>OK 버튼을 누른 후에 먼저 조이스틱을 수평으로 움직이고, 그 다음 수직으로 움직이세요.
축을 뒤집으려면 수직으로 먼저 움직인 뒤에 수평으로 움직이세요.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation>중심축</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>데드존: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>수정자 범위: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>프로 컨트롤러</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>듀얼 조이콘</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>왼쪽 조이콘</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>오른쪽 조이콘</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>휴대 모드</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>GameCube 컨트롤러</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>몬스터볼 Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>NES 컨트롤러</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>SNES 컨트롤러</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>N64 컨트롤러</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>세가 제네시스</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>시작 / 일시중지</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>컨트롤 스틱</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>흔드세요!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[대기중]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>새 프로필</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>프로필 이름을 입력하세요:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>입력 프로필 생성</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>해당 프로필 이름은 사용할 수 없습니다!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>&quot;%1&quot; 입력 프로필 생성 실패</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>입력 프로필 삭제</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>&quot;%1&quot; 입력 프로필 삭제 실패</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>입력 프로필 불러오기</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>&quot;%1&quot; 입력 프로필 불러오기 실패</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>입력 프로필 저장</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>&quot;%1&quot; 입력 프로필 저장 실패</translation>
</message>
@@ -2779,42 +2829,42 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation>개발자</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>부가 기능</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>일반</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>시스템</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>그래픽</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>고급 그래픽</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>오디오</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>속성</translation>
</message>
@@ -3526,47 +3576,47 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;TAS-nx 스크립트와 동일한 형식의 스크립트에서 컨트롤러 입력을 읽습니다.&lt;br/&gt;더 자세한 설명은 yuzu 웹사이트에 있는 &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;help page&lt;/span&gt;&lt;/a&gt;를 참조하세요.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>재생/녹화를 제어하는 ​​단축키를 확인하려면 단축키 설정(설정 -&gt; 일반 -&gt; 단축키)을 참조하십시오.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>경고: 이것은 실험적인 기능입니다.&lt;br/&gt;현재의 불완전한 동기화 방법으로는 스크립트 프레임을 완벽하게 재생하지 않습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>설정</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>TAS 기능 활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>반복 스크립트</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>로드 중 실행 일시중지</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>스크립트 주소</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>주소</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3976,7 +4026,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>인증</translation>
</message>
@@ -4003,7 +4053,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="118"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
- <translation type="unfinished"/>
+ <translation>웹 서비스 구성은 공개 방이 호스팅되지 않을 때만 변경할 수 있습니다.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="128"/>
@@ -4063,7 +4113,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>불특정</translation>
</message>
@@ -4078,17 +4128,36 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>토큰이 확인되지 않았습니다. 토큰 변경 사항이 저장되지 않을 것입니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation>인증되지 않음, 구성을 저장하기 전에 인증을 클릭하십시오.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>인증 중...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation>인증됨</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>인증 실패</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>인증 실패</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>인증 실패. 토큰을 올바르게 입력했는지, 그리고 인터넷이 연결되어 있는지 확인하십시오.</translation>
</message>
@@ -4111,972 +4180,952 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="14"/>
<source>Direct Connect</source>
- <translation type="unfinished"/>
+ <translation>직접 연결</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="33"/>
<source>IP Address</source>
- <translation type="unfinished"/>
+ <translation>IP 주소</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="56"/>
<source>IP</source>
- <translation type="unfinished"/>
+ <translation>IP</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="63"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;IPv4 address of the host&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;호스트의 IPv4 주소&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="73"/>
<source>Port</source>
- <translation type="unfinished"/>
+ <translation>포트</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="80"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Port number the host is listening on&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;호스트가 수신 대기 중인 포트 번호&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="100"/>
<source>Nickname</source>
- <translation type="unfinished"/>
+ <translation>별명</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="114"/>
<source>Password</source>
- <translation type="unfinished"/>
+ <translation>비밀번호</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="156"/>
<source>Connect</source>
- <translation type="unfinished"/>
+ <translation>연결</translation>
</message>
</context>
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
- <translation type="unfinished"/>
+ <translation>연결중</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
- <translation type="unfinished"/>
+ <translation>연결</translation>
</message>
</context>
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>yuzu를 개선하기 위해 &lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;익명 데이터가 수집됩니다.&lt;/a&gt; &lt;br/&gt;&lt;br/&gt;사용 데이터를 공유하시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>원격 측정</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation>망가진 Vulkan 설치 감지됨</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
- <translation type="unfinished"/>
+ <translation>부팅하는 동안 Vulkan 초기화에 실패했습니다.&lt;br&gt;&lt;br&gt;문제 해결 지침을 보려면 &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;여기&lt;/a&gt;를 클릭하세요.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>웹 애플릿을 로드하는 중...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>웹 애플릿 비활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>웹 애플릿을 비활성화하면 정의되지 않은 동작이 발생할 수 있으며 Super Mario 3D All-Stars에서만 사용해야 합니다. 웹 애플릿을 비활성화하시겠습니까?
(디버그 설정에서 다시 활성화할 수 있습니다.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>현재 생성중인 셰이더의 양</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>현재 선택된 해상도 배율입니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>현재 에뮬레이션 속도. 100%보다 높거나 낮은 값은 에뮬레이션이 Switch보다 빠르거나 느린 것을 나타냅니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>게임이 현재 표시하고 있는 초당 프레임 수입니다. 이것은 게임마다 다르고 장면마다 다릅니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>프레임 제한이나 수직 동기화를 계산하지 않고 Switch 프레임을 에뮬레이션 하는 데 걸린 시간. 최대 속도로 에뮬레이트 중일 때에는 대부분 16.67 ms 근처입니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>Clear Recent Files(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>재개(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>일시중지(&amp;P)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>yuzu가 게임을 실행중입니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>오래된 게임 포맷 경고</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>이 게임 파일은 &apos;분해된 ROM 디렉토리&apos;라는 오래된 포맷을 사용하고 있습니다. 해당 포맷은 NCA, NAX, XCI 또는 NSP와 같은 다른 포맷으로 대체되었으며 분해된 ROM 디렉토리에는 아이콘, 메타 데이터 및 업데이트가 지원되지 않습니다.&lt;br&gt;&lt;br&gt;yuzu가 지원하는 다양한 Switch 포맷에 대한 설명은 &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;위키를 확인하세요.&lt;/a&gt; 이 메시지는 다시 표시되지 않습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>ROM 로드 중 오류 발생!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>지원되지 않는 롬 포맷입니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>비디오 코어를 초기화하는 동안 오류가 발생했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>비디오 코어를 실행하는 동안 yuzu에 오류가 발생했습니다. 이것은 일반적으로 통합 드라이버를 포함하여 오래된 GPU 드라이버로 인해 발생합니다. 자세한 내용은 로그를 참조하십시오. 로그 액세스에 대한 자세한 내용은 &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;로그 파일 업로드 방법&lt;/a&gt; 페이지를 참조하세요.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>ROM 불러오는 중 오류 발생! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;파일들을 다시 덤프하기 위해&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu 빠른 시작 가이드&lt;/a&gt; 를 따라주세요.&lt;br&gt;도움이 필요할 시 yuzu 위키&lt;/a&gt; 를 참고하거나 yuzu 디스코드&lt;/a&gt; 를 이용해보세요.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>알 수 없는 오류가 발생했습니다. 자세한 내용은 로그를 참고하십시오.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64비트)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32비트)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>세이브 데이터</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>모드 데이터</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>%1 폴더 열기 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>폴더가 존재하지 않습니다!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>전송 가능한 셰이더 캐시 열기 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>이 타이틀에 대한 셰이더 캐시 디렉토리를 생성하지 못했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>컨텐츠</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>업데이트</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>항목 제거</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>설치된 게임을 삭제 %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>삭제 완료</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>설치된 기본 게임을 성공적으로 제거했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>삭제 중 오류 발생 %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>기본 게임은 NAND에 설치되어 있지 않으며 제거 할 수 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>설치된 업데이트를 성공적으로 제거했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>이 타이틀에 대해 설치된 업데이트가 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>이 타이틀에 설치된 DLC가 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>설치된 %1 DLC를 성공적으로 제거했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>OpenGL 전송 가능한 셰이더 캐시를 삭제하시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Vulkan 전송 가능한 셰이더 캐시를 삭제하시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>모든 전송 가능한 셰이더 캐시를 삭제하시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>사용자 지정 게임 구성을 제거 하시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>파일 제거</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>전송 가능한 셰이더 캐시 제거 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>이 타이틀에 대한 셰이더 캐시가 존재하지 않습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>전송 가능한 셰이더 캐시를 성공적으로 제거했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>전송 가능한 셰이더 캐시를 제거하지 못했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>전송 가능한 셰이더 캐시 제거 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>전송 가능한 셰이더 캐시를 성공적으로 제거했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>전송 가능한 셰이더 캐시 디렉토리를 제거하지 못했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>사용자 지정 구성 제거 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>이 타이틀에 대한 사용자 지정 구성이 존재하지 않습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>사용자 지정 게임 구성을 성공적으로 제거했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>사용자 지정 게임 구성을 제거하지 못했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS 추출 실패!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>RomFS 파일을 복사하는 중에 오류가 발생했거나 사용자가 작업을 취소했습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>전체</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>뼈대</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>RomFS 덤프 모드 선택</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>RomFS 덤프 방법을 선택하십시오.&lt;br&gt;전체는 모든 파일을 새 디렉토리에 복사하고&lt;br&gt;뼈대는 디렉토리 구조 만 생성합니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>%1에 RomFS를 추출하기에 충분한 여유 공간이 없습니다. 공간을 확보하거나 에뮬레이견 &gt; 설정 &gt; 시스템 &gt; 파일시스템 &gt; 덤프 경로에서 다른 덤프 디렉토리를 선택하십시오.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>RomFS 추출 중...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>취소</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS 추출이 성공했습니다!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>작업이 성공적으로 완료되었습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>%1 열기 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>경로 선택</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>속성</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>게임 속성을 로드 할 수 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch 실행파일 (%1);;모든 파일 (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>파일 로드</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>추출된 ROM 디렉토리 열기</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>잘못된 디렉토리 선택</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>선택한 디렉토리에 &apos;main&apos;파일이 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>설치 가능한 Switch 파일 (*.nca *.nsp *.xci);;Nintendo 컨텐츠 아카이브 (*.nca);;Nintendo 서브미션 패키지 (*.nsp);;NX 카트리지 이미지 (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>파일 설치</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n개의 파일이 남음</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>파일 &quot;%1&quot; 설치 중...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>설치 결과</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>충돌을 피하기 위해, 낸드에 베이스 게임을 설치하는 것을 권장하지 않습니다.
이 기능은 업데이트나 DLC를 설치할 때에만 사용해주세요.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n개의 파일이 새로 설치되었습니다.
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n개의 파일을 덮어썼습니다.
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n개의 파일을 설치하지 못했습니다.
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>시스템 애플리케이션</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>시스템 아카이브</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>시스템 애플리케이션 업데이트</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>펌웨어 패키지 (A타입)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>펌웨어 패키지 (B타입)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>게임</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>게임 업데이트</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>게임 DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>델타 타이틀</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>NCA 설치 유형 선택...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>이 NCA를 설치할 타이틀 유형을 선택하세요:
(대부분의 경우 기본값인 &apos;게임&apos;이 괜찮습니다.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>설치 실패</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>NCA 타이틀 유형이 유효하지 않습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>파일을 찾을 수 없음</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>파일 &quot;%1&quot;을 찾을 수 없습니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>yuzu 계정 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>게임 호환성 테스트 결과를 제출하려면 yuzu 계정을 연결해야합니다.&lt;br&gt;&lt;br/&gt;yuzu 계정을 연결하려면 에뮬레이션 &amp;gt; 설정 &amp;gt; 웹으로 가세요.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>URL 열기 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>URL &quot;%1&quot;을 열 수 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>TAS 레코딩</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>플레이어 1의 파일을 덮어쓰시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>유효하지 않은 설정 감지</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>휴대 모드용 컨트롤러는 거치 모드에서 사용할 수 없습니다. 프로 컨트롤러로 대신 선택됩니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation>현재 게임은 amiibo를 찾고 있지 않습니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation>현재 amiibo가 제거되었습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo 파일 (%1);; 모든 파일 (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Amiibo 로드</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Amiibo 데이터 파일 열기 오류</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Amiibo 파일 &quot;%1&quot;을(를) 읽을 수 없습니다.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Amiibo 데이터 파일 읽기 오류</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Amiibo 데이터를 완전히 읽을 수 없습니다. %1 바이트를 읽으려고 했지만 %2 바이트만 읽을 수 있었습니다.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Amiibo 데이터 로드 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Amiibo 데이터를 로드할 수 없습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>스크린샷 캡처</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>PNG 이미지 (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS 상태: %1/%2 실행 중</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>TAS 상태: 레코딩 %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAS 상태: 유휴 %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>TAS 상태: 유효하지 않음</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>실행 중지(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>시작(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>레코딩 중지(&amp;e)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>레코드(&amp;R)</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>빌드중: %n개 셰이더</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>스케일: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>속도: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>속도: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>게임: %1 FPS (제한없음)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>게임: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>프레임: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU 보통</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU 높음</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU 굉장함</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>GPU 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation>거치 모드</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation>휴대 모드</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>NEAREST</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>BILINEAR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>BICUBIC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>GAUSSIAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>AA 없음</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>해당 게임은 플레이하기 전에 Switch 기기에서 추가 파일을 덤프해야합니다.&lt;br/&gt;&lt;br/&gt;이러한 파일 덤프에 대한 자세한 내용은 다음 위키 페이지를 참조하십시오: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Switch 콘솔에서 시스템 아카이브 및 공유 글꼴 덤프&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;게임 목록으로 돌아가시겠습니까? 이를 무시하고 에뮬레이션을 계속하면 충돌, 저장 데이터 손상 또는 기타 버그가 발생할 수 있습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>yuzu가 Switch 시스템 아카이브를 찾을 수 없습니다. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>yuzu가 Switch 시스템 아카이브를 찾을 수 없습니다: %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>시스템 아카이브를 찾을 수 없음</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>시스템 아카이브 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu가 Switch 공유 글꼴을 찾을 수 없습니다. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>공유 글꼴을 찾을 수 없음</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>공유 글꼴 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>치명적인 오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>치명적인 오류가 발생했습니다. 자세한 내용은 로그를 확인하십시오. 로그 액세스에 대한 자세한 내용은 다음 페이지를 참조하십시오: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;로그 파일을 업로드하는 방법&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;게임 목록으로 돌아가시겠습니까? 이를 무시하고 에뮬레이션을 계속하면 충돌, 저장 데이터 손상 또는 기타 버그가 발생할 수 있습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>치명적인 오류 발생</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>키 재생성 확인</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5093,37 +5142,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
자동 생성되었던 키 파일들이 삭제되고 키 생성 모듈이 다시 실행됩니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>fuses 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation> - BOOT0 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - BCPKG2-1-Normal-Main 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation> - PRODINFO 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>파생 구성 요소 누락</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>암호화 키가 없습니다. &lt;br&gt;모든 키, 펌웨어 및 게임을 얻으려면 &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu 빠른 시작 가이드&lt;/a&gt;를 따르세요.&lt;br&gt;&lt;br&gt; &lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5132,39 +5181,39 @@ on your system&apos;s performance.</source>
소요될 수 있습니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>파생 키</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>RomFS 덤프 대상 선택</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>덤프할 RomFS를 선택하십시오.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>yuzu를 닫으시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>에뮬레이션을 중지하시겠습니까? 모든 저장되지 않은 진행 상황은 사라집니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5480,22 +5529,22 @@ Screen.</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="14"/>
<source>Create Room</source>
- <translation type="unfinished"/>
+ <translation>방 만들기</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="37"/>
<source>Room Name</source>
- <translation type="unfinished"/>
+ <translation>방 이름</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="51"/>
<source>Preferred Game</source>
- <translation type="unfinished"/>
+ <translation>선호하는 게임</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="61"/>
<source>Max Players</source>
- <translation type="unfinished"/>
+ <translation>최대 플레이어</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="91"/>
@@ -5505,66 +5554,68 @@ Screen.</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="101"/>
<source>(Leave blank for open game)</source>
- <translation type="unfinished"/>
+ <translation>(열린 게임은 공백으로 둠)</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="118"/>
<source>Password</source>
- <translation type="unfinished"/>
+ <translation>비밀번호</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="125"/>
<source>Port</source>
- <translation type="unfinished"/>
+ <translation>포트</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="139"/>
<source>Room Description</source>
- <translation type="unfinished"/>
+ <translation>방 설명</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="153"/>
<source>Load Previous Ban List</source>
- <translation type="unfinished"/>
+ <translation>이전 차단 목록 불러오기</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="184"/>
<source>Public</source>
- <translation type="unfinished"/>
+ <translation>공개</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="189"/>
<source>Unlisted</source>
- <translation type="unfinished"/>
+ <translation>비공개</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="197"/>
<source>Host Room</source>
- <translation type="unfinished"/>
+ <translation>호스트 방</translation>
</message>
</context>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>오류</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
- <translation type="unfinished"/>
+ <translation>공개 로비에 방을 알리지 못했습니다. 방을 공개적으로 호스트하려면 에뮬레이션 -&gt; 구성 -&gt; 웹에서 유효한 yuzu 계정이 구성되어 있어야 합니다. 공개 로비에 방을 게시하지 않으려면 대신 목록에 없음을 선택하세요.
+디버그 메시지:</translation>
</message>
</context>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation>오디오 음소거/음소거 해제</translation>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5586,112 +5637,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation>메인 윈도우</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation>오디오 볼륨 낮추기</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation>오디오 볼륨 키우기</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>스크린샷 캡처</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation>적응형 필터 변경</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation>독 모드 변경</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation>GPU 정확성 변경</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation>재개/에뮬레이션 일시중지</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation>전체화면 종료</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation>yuzu 종료</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>전체화면</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>파일 로드</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation>Amiibo 로드/제거</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation>에뮬레이션 재시작</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation>에뮬레이션 중단</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation>TAS 기록</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation>TAS 리셋</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation>TAS 시작/멈춤</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation>상태 표시줄 전환</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation>프레임속도 제한 토글</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation>마우스 패닝 활성화</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation>상태 표시줄 전환</translation>
</message>
@@ -5772,78 +5822,78 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="14"/>
<source>Public Room Browser</source>
- <translation type="unfinished"/>
+ <translation>공개 방 찾아보기</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="32"/>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="39"/>
<source>Nickname</source>
- <translation type="unfinished"/>
+ <translation>별명</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="59"/>
<source>Filters</source>
- <translation type="unfinished"/>
+ <translation>필터</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="66"/>
<source>Search</source>
- <translation type="unfinished"/>
+ <translation>검색</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="76"/>
<source>Games I Own</source>
- <translation type="unfinished"/>
+ <translation>게임 I 주인</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="83"/>
<source>Hide Full Rooms</source>
- <translation type="unfinished"/>
+ <translation>전체 방 숨기기</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="103"/>
<source>Refresh Lobby</source>
- <translation type="unfinished"/>
+ <translation>로비 새로 고침</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
- <translation type="unfinished"/>
+ <translation>가입에 필요한 비밀번호</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
- <translation type="unfinished"/>
+ <translation>비밀번호:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
- <translation type="unfinished"/>
+ <translation>방 이름</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
- <translation type="unfinished"/>
+ <translation>선호하는 게임</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
- <translation type="unfinished"/>
+ <translation>호스트</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
- <translation type="unfinished"/>
+ <translation>플레이어</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
- <translation type="unfinished"/>
+ <translation>새로 고치는 중</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
- <translation type="unfinished"/>
+ <translation>새로 고침 목록</translation>
</message>
</context>
<context>
@@ -6001,27 +6051,27 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/main.ui" line="254"/>
<source>Browse Public Game Lobby</source>
- <translation type="unfinished"/>
+ <translation>공개 게임 로비 찾아보기</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="262"/>
<source>Create Room</source>
- <translation type="unfinished"/>
+ <translation>방 만들기</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="270"/>
<source>Leave Room</source>
- <translation type="unfinished"/>
+ <translation>방 나가기</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="275"/>
<source>Direct Connect to Room</source>
- <translation type="unfinished"/>
+ <translation>방에 직접 연결</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="283"/>
<source>Show Current Room</source>
- <translation type="unfinished"/>
+ <translation>현재 방 보기</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="291"/>
@@ -6107,48 +6157,48 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="6"/>
<source>Moderation</source>
- <translation type="unfinished"/>
+ <translation>조정</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="20"/>
<source>Ban List</source>
- <translation type="unfinished"/>
+ <translation>차단 목록</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="41"/>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="73"/>
<source>Refreshing</source>
- <translation type="unfinished"/>
+ <translation>새로 고치는 중</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="51"/>
<source>Unban</source>
- <translation type="unfinished"/>
+ <translation>차단 해재</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="40"/>
<source>Subject</source>
- <translation type="unfinished"/>
+ <translation>주제</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="41"/>
<source>Type</source>
- <translation type="unfinished"/>
+ <translation>유형</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="83"/>
<source>Forum Username</source>
- <translation type="unfinished"/>
+ <translation>포럼 사용자이름</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="88"/>
<source>IP Address</source>
- <translation type="unfinished"/>
+ <translation>IP 주소</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="95"/>
<source>Refresh</source>
- <translation type="unfinished"/>
+ <translation>새로 고침</translation>
</message>
</context>
<context>
@@ -6157,18 +6207,18 @@ Debug Message: </source>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="47"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="91"/>
<source>Current connection status</source>
- <translation type="unfinished"/>
+ <translation>현재 연결 상태</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="48"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="94"/>
<source>Not Connected. Click here to find a room!</source>
- <translation type="unfinished"/>
+ <translation>연결되지 않았습니다. 방을 찾으려면 여기를 클릭하세요!</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>연결됨</translation>
</message>
@@ -6176,7 +6226,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="99"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="128"/>
<source>Not Connected</source>
- <translation type="unfinished"/>
+ <translation>연결되지 않음</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="181"/>
@@ -6187,12 +6237,13 @@ Debug Message: </source>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="182"/>
<source>Failed to update the room information. Please check your Internet connection and try hosting the room again.
Debug Message: </source>
- <translation type="unfinished"/>
+ <translation>방 정보를 업데이트하지 못했습니다. 인터넷 연결을 확인하고 방을 다시 호스팅해 보세요.
+디버그 메시지:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
- <translation type="unfinished"/>
+ <translation>수신된 새 메시지</translation>
</message>
</context>
<context>
@@ -6200,124 +6251,144 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="11"/>
<source>Username is not valid. Must be 4 to 20 alphanumeric characters.</source>
- <translation type="unfinished"/>
+ <translation>사용자 이름이 유효하지 않습니다. 4~20자의 영숫자여야 합니다.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="13"/>
<source>Room name is not valid. Must be 4 to 20 alphanumeric characters.</source>
- <translation type="unfinished"/>
+ <translation>방 이름이 유효하지 않습니다. 4~20자의 영숫자여야 합니다.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="15"/>
<source>Username is already in use or not valid. Please choose another.</source>
- <translation type="unfinished"/>
+ <translation>사용자 이름은 이미 사용 중이거나 유효하지 않습니다. 다른 것을 선택하세요.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="17"/>
<source>IP is not a valid IPv4 address.</source>
- <translation type="unfinished"/>
+ <translation>IP는 유효한 IPv4 주소가 아닙니다.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="19"/>
<source>Port must be a number between 0 to 65535.</source>
- <translation type="unfinished"/>
+ <translation>포트는 0에서 65535 사이의 숫자여야 합니다.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="20"/>
<source>You must choose a Preferred Game to host a room. If you do not have any games in your game list yet, add a game folder by clicking on the plus icon in the game list.</source>
- <translation type="unfinished"/>
+ <translation>방을 호스팅하려면 선호하는 게임을 선택해야 합니다. 아직 게임 목록에 게임이 없으면 게임 목록에서 더하기 아이콘을 클릭하여 게임 폴더를 추가하세요.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="24"/>
<source>Unable to find an internet connection. Check your internet settings.</source>
- <translation type="unfinished"/>
+ <translation>인터넷 연결을 찾을 수 없습니다. 인터넷 설정을 확인하세요.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="26"/>
<source>Unable to connect to the host. Verify that the connection settings are correct. If you still cannot connect, contact the room host and verify that the host is properly configured with the external port forwarded.</source>
- <translation type="unfinished"/>
+ <translation>호스트에 연결할 수 없습니다. 연결 설정이 올바른지 확인하세요. 여전히 연결할 수 없으면 방 주인에게 연락하여 호스트가 전달된 외부 포트로 올바르게 구성되었는지 확인하세요.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="30"/>
<source>Unable to connect to the room because it is already full.</source>
- <translation type="unfinished"/>
+ <translation>이미 꽉 찼기 때문에 방에 연결할 수 없습니다.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="32"/>
<source>Creating a room failed. Please retry. Restarting yuzu might be necessary.</source>
- <translation type="unfinished"/>
+ <translation>방을 만들지 못했습니다. 다시 시도하세요. yuzu를 다시 시작해야 할 수도 있습니다.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="34"/>
<source>The host of the room has banned you. Speak with the host to unban you or try a different room.</source>
- <translation type="unfinished"/>
+ <translation>방 주인이 당신을 차단했습니다. 주인과 대화하여 차단을 해제하거나 다른 방을 사용해 보세요.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="37"/>
<source>Version mismatch! Please update to the latest version of yuzu. If the problem persists, contact the room host and ask them to update the server.</source>
- <translation type="unfinished"/>
+ <translation>버전이 불일치합니다! 최신 버전의 yuzu로 업데이트하세요. 문제가 지속되면 방 주인에게 연락하여 서버 업데이트를 요청하세요.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="39"/>
<source>Incorrect password.</source>
- <translation type="unfinished"/>
+ <translation>잘못된 비밀번호입니다.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="40"/>
<source>An unknown error occurred. If this error continues to occur, please open an issue</source>
- <translation type="unfinished"/>
+ <translation>알 수없는 오류가 발생했습니다. 이 오류가 계속 발생하면 문제를 알려주세요.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="43"/>
<source>Connection to room lost. Try to reconnect.</source>
- <translation type="unfinished"/>
+ <translation>방과의 연결이 끊어졌습니다. 다시 연결해 보세요.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="45"/>
<source>You have been kicked by the room host.</source>
- <translation type="unfinished"/>
+ <translation>방 주인에게 추방당했습니다.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="47"/>
<source>IP address is already in use. Please choose another.</source>
- <translation type="unfinished"/>
+ <translation>IP 주소는 이미 사용 중입니다. 다른 것을 선택하세요.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="49"/>
<source>You do not have enough permission to perform this action.</source>
- <translation type="unfinished"/>
+ <translation>이 작업을 수행할 수 있는 권한이 없습니다.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="50"/>
<source>The user you are trying to kick/ban could not be found.
They may have left the room.</source>
- <translation type="unfinished"/>
+ <translation>추방/금지하려는 사용자를 찾을 수 없습니다.
+방을 나갔을 수 있습니다.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation>네트워크 인터페이스가 선택되지 않았습니다.
+구성 -&gt; 시스템 -&gt; 네트워크로 이동하여 선택하십시오.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation>게임이 이미 실행 중입니다</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation>게임이 이미 실행 중일 때 방에 참여하는 것은 권장되지 않으며 방 기능이 제대로 작동하지 않을 수 있습니다.
+그래도 진행하시겠습니까?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
- <translation type="unfinished"/>
+ <translation>방 나가기</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
- <translation type="unfinished"/>
+ <translation>방을 닫으려고 합니다. 모든 네트워크 연결이 닫힙니다.</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
- <translation type="unfinished"/>
+ <translation>연결 해제</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
- <translation type="unfinished"/>
+ <translation>방을 떠나려고 합니다. 모든 네트워크 연결이 닫힙니다.</translation>
</message>
</context>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>오류</translation>
</message>
@@ -6368,17 +6439,17 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/multiplayer/lobby_p.h" line="230"/>
<source>%1 is not playing a game</source>
- <translation type="unfinished"/>
+ <translation>%1은(는) 게임을 하고 있지 않습니다</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby_p.h" line="232"/>
<source>%1 is playing %2</source>
- <translation type="unfinished"/>
+ <translation>%1이(가) %2을(를) 플레이 중입니다</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
- <translation type="unfinished"/>
+ <translation>게임을 하지 않음</translation>
</message>
<message>
<location filename="../../src/yuzu/game_list_p.h" line="242"/>
@@ -6431,7 +6502,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[설정 안 됨]</translation>
</message>
@@ -6446,10 +6517,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>축 %1%2</translation>
</message>
@@ -6463,9 +6534,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[알 수 없음]</translation>
</message>
@@ -6630,15 +6701,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[유효하지않음]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation>%1%2방향키 %3</translation>
</message>
@@ -6646,35 +6717,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation>%1%2Axis %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation>%1%2Axis %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2모션 %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2버튼 %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[미사용]</translation>
</message>
@@ -6715,7 +6786,7 @@ p, li { white-space: pre-wrap; }
<translation>Extra</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/languages/nb.ts b/dist/languages/nb.ts
index a5e68cec3..79ada55b2 100644
--- a/dist/languages/nb.ts
+++ b/dist/languages/nb.ts
@@ -89,78 +89,78 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -746,200 +746,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Aktiver GDB Stub</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Port:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Loggføring</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Global Loggfilter</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Vis logg i konsollen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Åpne Logg-Plassering</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Når dette er på øker maksstørrelsen til loggen fra 100 MB til 1 GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Slå på utvidet loggføring**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Argument streng</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Grafikk</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Når dette er på går grafikk–API-et inn i en tregere feilsøkingsmodus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Slå på Grafikkfeilsøking</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>Slå på shader-tilbakemelding</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>Når dette er på kjører shader-e uten endring i løkkelogikk</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Feilsøking</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
- <source>Enable FS Access Log</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Avansert</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Slå på prosessorfeilsøking</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Slå av web-applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Dette blir automatisk tilbakestilt når yuzu lukkes.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1558,37 +1593,47 @@ This would ban both their forum username and their IP address.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Anisotropisk filtrering:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>Automatisk</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Standard</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2080,7 +2125,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Venstre Pinne</translation>
</message>
@@ -2174,14 +2219,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2200,7 +2245,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Pluss</translation>
</message>
@@ -2213,15 +2258,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2278,231 +2323,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Høyre Pinne</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Fjern</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[ikke satt]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Veksle knapp</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>Inverter knapp</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Veksle knapp</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Inverter akse</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>Set grense</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Velg en verdi mellom 0% og 100%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Etter du har trykker på OK, flytt først stikken horisontalt, og så vertikalt.
For å invertere aksene, flytt først stikken vertikalt, og så horistonalt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation>Senterakse</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Dødsone: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Modifikatorområde: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Pro-Kontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Doble Joycons</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Venstre Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Høyre Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Håndholdt</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>GameCube-kontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>NES-kontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>SNES-kontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>N64-kontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Start / paus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Kontrollstikke</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-stikke</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Rist!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[venter]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Ny Profil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Skriv inn et profilnavn:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Lag inndataprofil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>Det oppgitte profilenavnet er ugyldig!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Klarte ikke lage inndataprofil &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Slett inndataprofil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Klarte ikke slette inndataprofil &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Last inn inndataprofil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Klarte ikke laste inn inndataprofil &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Lagre inndataprofil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Klarte ikke lagre inndataprofil &quot;%1&quot;</translation>
</message>
@@ -2757,42 +2807,42 @@ For å invertere aksene, flytt først stikken vertikalt, og så horistonalt.</tr
<translation>Utvikler</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Tillegg</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Generelt</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>System</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Grafikk</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Avn. Grafikk</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Lyd</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Egenskaper</translation>
</message>
@@ -3504,47 +3554,47 @@ For å invertere aksene, flytt først stikken vertikalt, og så horistonalt.</tr
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Leser kontrollerinndata fra script i samme format som TAS-nx–script.&lt;br/&gt;For en mer detaljert beskrivelse, se &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;hjelpesiden&lt;/span&gt;&lt;/a&gt; på yuzus hjemmeside.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>For å sjekke hvilke hurtigtaster som styrer avspilling/innspilling, se hurtigtastinnstillingene (Konfigurer -&gt; Generelt -&gt; Hurtigtaster).</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>ADVARSEL: Dette er eksperimentell funksjonalitet.&lt;br/&gt;Script spilles ikke tilbake med perfekt bildetiming med den nåværende, ikke-perfekte synkemetoden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Innstillinger</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>Slå på TAS-funksjonalitet</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>Sett kjøring på vent under lasting</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>Skriptmappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Sti</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3954,7 +4004,7 @@ Dra punkter for å endre posisjon, eller dobbelttrykk på tabellfelter for å re
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Verifiser</translation>
</message>
@@ -4041,7 +4091,7 @@ Dra punkter for å endre posisjon, eller dobbelttrykk på tabellfelter for å re
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Uspesifisert</translation>
</message>
@@ -4056,17 +4106,36 @@ Dra punkter for å endre posisjon, eller dobbelttrykk på tabellfelter for å re
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Verifiserer...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Verifisering feilet</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Verifisering feilet</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation type="unfinished"/>
</message>
@@ -4135,12 +4204,12 @@ Dra punkter for å endre posisjon, eller dobbelttrykk på tabellfelter for å re
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation type="unfinished"/>
</message>
@@ -4148,486 +4217,486 @@ Dra punkter for å endre posisjon, eller dobbelttrykk på tabellfelter for å re
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonym data blir samlet inn&lt;/a&gt;for å hjelpe til med å forbedre yuzu.&lt;br/&gt;&lt;br/&gt;Vil du dele din bruksdata med oss?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Laster web-applet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Slå av web-applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>Antall shader-e som bygges for øyeblikket</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Den valgte oppløsningsskaleringsfaktoren.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Nåværende emuleringshastighet. Verdier høyere eller lavere en 100% indikerer at emuleringen kjører raskere eller tregere enn en Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Hvor mange bilder per sekund spiller viser. Dette vil variere fra spill til spill og scene til scene.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tid det tar for å emulere et Switch bilde. Teller ikke med bildebegrensing eller v-sync. For full-hastighet emulering burde dette være 16.67 ms. på det høyeste.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Paus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>Et spill kjører i yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Advarsel: Utdatert Spillformat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Du bruker en dekonstruert ROM-mappe for dette spillet, som er et utdatert format som har blitt erstattet av andre formater som NCA, NAX, XCI, eller NSP. Dekonstruerte ROM-mapper mangler ikoner, metadata, og oppdateringsstøtte.&lt;br&gt;&lt;br&gt;For en forklaring på diverse Switch-formater som yuzu støtter,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;sjekk vår wiki&lt;/a&gt;. Denne meldingen vil ikke bli vist igjen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Feil under innlasting av ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>Dette ROM-formatet er ikke støttet.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>En feil oppstod under initialisering av videokjernen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu har oppdaget en feil under kjøring av videokjernen. Dette er vanligvis forårsaket av utdaterte GPU-drivere, inkludert for integrert grafikk. Vennligst sjekk loggen for flere detaljer. For mer informasjon om å finne loggen, besøk følgende side: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Uploadd the Log File&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Feil under lasting av ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>En ukjent feil oppstod. Se loggen for flere detaljer.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Lagre Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Mod Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Feil Under Åpning av %1 Mappen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Mappen eksisterer ikke!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Innhold</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Oppdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Fjern oppføring</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>Fjern Installert Spill %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>Fjerning lykkes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>Feil Under Fjerning av %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Grunnspillet er ikke installert i NAND og kan ikke bli fjernet.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>Fjernet vellykket den installerte oppdateringen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>Det er ingen oppdatering installert for denne tittelen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>Det er ingen DLC installert for denne tittelen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Fjernet vellykket %1 installerte DLC-er.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>Fjern Tilpasset Spillkonfigurasjon?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Fjern Fil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Feil under fjerning av overførbar shader cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Lykkes i å fjerne den overførbare shader cachen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Feil under fjerning av den overførbare shader cachen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Feil Under Fjerning Av Tilpasset Konfigurasjon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>En tilpasset konfigurasjon for denne tittelen finnes ikke.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Fjernet vellykket den tilpassede spillkonfigurasjonen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Feil under fjerning av den tilpassede spillkonfigurasjonen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>Utvinning av RomFS Feilet!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Det oppstod en feil under kopiering av RomFS filene eller så kansellerte brukeren operasjonen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Fullstendig</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Skjelett</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Velg RomFS Dump Modus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Velg hvordan du vil dumpe RomFS.&lt;br&gt;Fullstendig vil kopiere alle filene til en ny mappe mens &lt;br&gt;skjelett vil bare skape mappestrukturen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Utvinner RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Avbryt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS Utpakking lyktes!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>Operasjonen fullført vellykket.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Feil ved åpning av %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Velg Mappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Egenskaper</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Spillets egenskaper kunne ikke bli lastet inn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch Kjørbar Fil (%1);;Alle Filer (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Last inn Fil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Åpne Utpakket ROM Mappe</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Ugyldig Mappe Valgt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Mappen du valgte inneholder ikke en &apos;main&apos; fil.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Installerbar Switch-Fil (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xcI)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Installer Filer</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n fil gjenstår</numerusform><numerusform>%n filer gjenstår</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Installerer fil &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Insallasjonsresultater</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n fil ble nylig installert
@@ -4635,7 +4704,7 @@ Please, only use this feature to install updates and DLC.</source>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n fil ble overskrevet
@@ -4643,7 +4712,7 @@ Please, only use this feature to install updates and DLC.</source>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n fil ble ikke installert
@@ -4651,411 +4720,391 @@ Please, only use this feature to install updates and DLC.</source>
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Systemapplikasjon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Systemarkiv</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Systemapplikasjonsoppdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Firmware Pakke (Type A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Firmware-Pakke (Type B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Spill</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Spilloppdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>Spill tilleggspakke</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Delta Tittel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Velg NCA Installasjonstype...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Vennligst velg typen tittel du vil installere denne NCA-en som:
(I de fleste tilfellene, standarden &apos;Spill&apos; fungerer.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Feil under Installasjon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Titteltypen du valgte for NCA-en er ugyldig.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Fil ikke funnet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Filen &quot;%1&quot; ikke funnet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Mangler yuzu Bruker</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>For å sende inn et testtilfelle for spillkompatibilitet, må du linke yuzu-brukeren din.&lt;br&gt;&lt;br/&gt;For å linke yuzu-brukeren din, gå til Emulasjon &amp;gt; Konfigurasjon &amp;gt; Nett.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Feil under åpning av URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Kunne ikke åpne URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>TAS-innspilling</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>Overskriv filen til spiller 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>Ugyldig konfigurasjon oppdaget</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Håndholdt kontroller kan ikke brukes i dokket modus. Pro-kontroller vil bli valgt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>Feil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation>Det kjørende spillet sjekker ikke for amiibo-er</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation>Den valgte amiibo-en har blitt fjernet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo-Fil (%1);; Alle Filer (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Last inn Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Feil ved Åpning av Amiibo data fil</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Kunne ikke åpne Amiibo-fil &quot;%1&quot; for lesing.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Feil under lesing av Amiibo datafil.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Kunne ikke lese all Amiibo-data. Forventet å lese minst %1 bytes, men kunne bare lese %2 bytes.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Feil ved lasting av Amiibo data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Kunne ikke laste Amiibo-data.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Ta Skjermbilde</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>PNG Bilde (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS-tilstand: Kjører %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>TAS-tilstand: Spiller inn %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAS-tilstand: Venter %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>TAS-tilstand: Ugyldig</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>&amp;Stopp kjøring</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Bygger: %n shader</numerusform><numerusform>Bygger: %n shader-e</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Skala: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Hastighet: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Hastighet: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Spill: %1 FPS (ubegrenset)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Spill: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Ramme: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU HØY</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU EKSTREM</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>GPU FEIL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>NÆRMESTE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>BILINEÆR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>BIKUBISK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>GAUSSISK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>INGEN AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>Spillet du prøver å laste krever at ekstra filer fra din Switch blir dumpet før du spiller.&lt;br/&gt;&lt;br/&gt;For mer informasjon om dumping av disse filene, vennligst se den følgende wiki-siden: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping av System-Arkiv og Shared Fonts fra en Switch-Konsoll&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Vil du gå tilbake til spillisten? Fortsetting av emulasjon kan føre til krasjing, ødelagt lagringsdata, eller andre feil.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>yuzu kunne ikke finne et Switch system-arkiv. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>yuzu kunne ikke finne et Switch system-arkiv: %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>System Arkiv Ikke Funnet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>System Arkiv Mangler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu kunne ikke finne Switch shared fonts. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Shared Fonts Ikke Funnet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Shared Font Mangler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Fatal Feil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu har oppdaget en fatal feil, vennligst se loggen for flere detaljer. For mer informasjon om å finne loggen, vennligst se den følgende siden: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Hvordan å Laste Opp Log-Filen&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Vil du gå tilbake til spillisten? Fortsetting av emulasjon kan føre til krasjing, ødelagt lagringsdata, eller andre feil.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Fatal Feil oppstått</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Bekreft Nøkkel-Redirevasjon</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5072,37 +5121,37 @@ og eventuelt lag backups.
Dette vil slette dine autogenererte nøkkel-filer og kjøre nøkkel-derivasjonsmodulen på nytt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>Mangler fuses</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation>- Mangler BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- Mangler BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation>- Mangler PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>Derivasjonskomponenter Mangler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Krypteringsnøkler mangler. &lt;br&gt;Vennligst følg &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzus oppstartsguide&lt;/a&gt; for å få alle nøklene, fastvaren og spillene dine.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5111,39 +5160,39 @@ Dette kan ta opp til et minutt avhengig
av systemytelsen din.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Deriverer Nøkler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Velg RomFS Dump-Mål</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Vennligst velg hvilken RomFS du vil dumpe.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Er du sikker på at du vil lukke yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Er du sikker på at du vil stoppe emulasjonen? All ulagret fremgang vil bli tapt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5520,12 +5569,12 @@ Screen.</source>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>Feil</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5534,11 +5583,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5560,112 +5610,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Ta Skjermbilde</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Fullskjerm</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Last inn Fil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5780,42 +5829,42 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Spillere</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation type="unfinished"/>
</message>
@@ -6142,7 +6191,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Tilkoblet</translation>
</message>
@@ -6164,7 +6213,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation type="unfinished"/>
</message>
@@ -6268,22 +6317,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6291,7 +6357,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>Feil</translation>
</message>
@@ -6350,7 +6416,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation type="unfinished"/>
</message>
@@ -6405,7 +6471,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[ikke satt]</translation>
</message>
@@ -6420,10 +6486,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Akse %1%2</translation>
</message>
@@ -6437,9 +6503,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[ukjent]</translation>
</message>
@@ -6604,15 +6670,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[ugyldig]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation type="unfinished"/>
</message>
@@ -6620,35 +6686,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation>%1%2Akse %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation>%1%2Akse %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2Bevegelse %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2Knapp %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[ubrukt]</translation>
</message>
@@ -6689,7 +6755,7 @@ p, li { white-space: pre-wrap; }
<translation>Ekstra</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/languages/nl.ts b/dist/languages/nl.ts
index e42dbb519..a6fe4274d 100644
--- a/dist/languages/nl.ts
+++ b/dist/languages/nl.ts
@@ -89,78 +89,78 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -743,200 +743,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>GDB Stub Aanzetten</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Poort:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Loggen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Globale Log Filter</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Laat Log Venster Zien</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Open Log Locatie</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Indien aangevinkt, neemt de maximale grootte van de log toe van 100 MB tot 1 GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Activeer Uitgebreid Loggen**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Argumenten Rij</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Graphics</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Indien aangevinkt, gaat de grafische API naar een langzamere foutopsporingsmodus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Grafische foutopsporing inschakelen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>Indien aangevinkt, wordt de macro Just In Time-compiler uitgeschakeld. Als u dit inschakelt, worden games langzamer</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Schakel Macro JIT uit</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Debugging</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
- <source>Enable FS Access Log</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Geavanceerd</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Kiosk (Quest) Modus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Schakel Debug asserties in</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Deze optie wordt automatisch gereset wanneer yuzu is gesloten.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1556,37 +1591,47 @@ This would ban both their forum username and their IP address.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Anisotrope Filtering:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Standaard</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2078,7 +2123,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Linker Stick</translation>
</message>
@@ -2172,14 +2217,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2198,7 +2243,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Plus:</translation>
</message>
@@ -2211,15 +2256,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2276,231 +2321,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Rechter Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Verwijder</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[niet ingesteld]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Shakel Knop</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Shakel Knop</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Spiegel As</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Zet Analoge Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Na OK in te drukken, beweeg je joystick eerst horizontaal en dan verticaal.
Om de assen te spiegelen, beweek je joystick eerst verticaal en dan horizontaal.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Deadzone: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Bewerk Range: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Twee Joycons</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Linker Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Rechter Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Mobiel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>GameCube Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Start / Pauze</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Control Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Shudden!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[aan het wachten]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Nieuw Profiel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Voer nieuwe gebruikersnaam in:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Creëer een nieuw Invoer Profiel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>De ingevoerde Profiel naam is niet geldig</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Het is mislukt om Invoer Profiel &quot;%1 te Creëer</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Verwijder invoer profiel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Het is mislukt om Invoer Profiel &quot;%1 te Verwijderen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Laad invoer profiel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Het is mislukt om Invoer Profiel &quot;%1 te Laden</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Sla Invoer profiel op</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Het is mislukt om Invoer Profiel &quot;%1 Op te slaan</translation>
</message>
@@ -2755,42 +2805,42 @@ Om de assen te spiegelen, beweek je joystick eerst verticaal en dan horizontaal.
<translation>Ontwikkelaar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Add-Ons</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Algemeen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Systeem</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Grafisch</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Adv. Grafisch</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Geluid</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Eigenschappen</translation>
</message>
@@ -3502,47 +3552,47 @@ Om de assen te spiegelen, beweek je joystick eerst verticaal en dan horizontaal.
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Pad</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3952,7 +4002,7 @@ Sleep punten om positie te veranderen, of dubbel klik één van de tabel cellen
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Verifieer</translation>
</message>
@@ -4039,7 +4089,7 @@ Sleep punten om positie te veranderen, of dubbel klik één van de tabel cellen
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Niet gespecificeerd</translation>
</message>
@@ -4054,17 +4104,36 @@ Sleep punten om positie te veranderen, of dubbel klik één van de tabel cellen
<translation>Token is niet geverifieerd. De verandering aan uw token zijn niet opgeslagen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Verifiëren...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Verificatie mislukt</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Verificatie mislukt</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Verificatie mislukt. Check dat uw token correct is en dat uw internet werkt.</translation>
</message>
@@ -4133,12 +4202,12 @@ Sleep punten om positie te veranderen, of dubbel klik één van de tabel cellen
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation type="unfinished"/>
</message>
@@ -4146,908 +4215,888 @@ Sleep punten om positie te veranderen, of dubbel klik één van de tabel cellen
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Annonieme gegevens worden verzameld&lt;/a&gt; om yuzu te helpen verbeteren. &lt;br/&gt;&lt;br/&gt; Zou je jouw gebruiksgegevens met ons willen delen?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetrie</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Web Applet Laden...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Huidige emulatie snelheid. Waardes hoger of lager dan 100% betekent dat de emulatie sneller of langzamer loopt dan de Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Hoeveel frames per seconde de game op dit moment weergeeft. Dit zal veranderen van game naar game en van scène naar scène.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tijd gebruikt om een frame van de Switch te emuleren, waarbij framelimiteren of v-sync niet wordt meegerekend. Voor emulatie op volledige snelheid zou dit maximaal 16.67 ms zijn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Pauzeren</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Waarschuwing Verouderd Spel Formaat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Je gebruikt gedeconstrueerd ROM map formaat voor dit Spel, dit is een verouderd formaat en is vervangen door formaten zoals NCA, NAX, XCI of NSP. Gedeconstrueerd ROM map heeft geen iconen, metadata en update understeuning.&lt;br&gt;&lt;br&gt;Voor een uitleg over welke Switch formaten yuzu ondersteund, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;kijk op onze wiki&lt;/a&gt;. Dit bericht word niet nog een keer weergegeven.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Fout tijdens het laden van een ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>Het formaat van de ROM is niet ondersteunt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Er is een fout opgetreden tijdens het initialiseren van de videokern.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Een onbekende fout heeft plaatsgevonden. Kijk in de log voor meer details.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Save Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Mod Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Fout tijdens het openen van %1 folder</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Folder bestaat niet!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Fout Bij Het Openen Van Overdraagbare Shader Cache</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>Er bestaat geen shader cache voor deze game</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS Extractie Mislukt!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Er was een fout tijdens het kopiëren van de RomFS bestanden of de gebruiker heeft de operatie geannuleerd.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Vol</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Skelet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Selecteer RomFS Dump Mode</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Selecteer alstublieft hoe je de RomFS wilt dumpen.&lt;br&gt;Volledig kopieërd alle bestanden in een map terwijl &lt;br&gt; skelet maakt alleen het map structuur.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>RomFS uitpakken...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Annuleren</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS Extractie Geslaagd!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>De operatie is succesvol voltooid.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Fout bij openen %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Selecteer Map</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Eigenschappen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>De eigenschappen van de game kunnen niet geladen worden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch Executable (%1);;Alle bestanden (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Laad Bestand</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Open Gedecomprimeerd ROM Map</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Ongeldige Map Geselecteerd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>De map die je hebt geselecteerd bevat geen &apos;main&apos; bestand.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Bestand &quot;%1&quot; Installeren...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Systeem Applicatie</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Systeem Archief</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Systeem Applicatie Update</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Filmware Pakket (Type A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Filmware Pakket (Type B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Game</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Game Update</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>Game DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Delta Titel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Selecteer NCA Installatie Type...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Selecteer het type titel hoe je wilt dat deze NCA installeerd:
(In de meeste gevallen is de standaard &apos;Game&apos; juist.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Installatie Mislukt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Het type title dat je hebt geselecteerd voor de NCA is ongeldig.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Bestand niet gevonden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Bestand &quot;%1&quot; niet gevonden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Je yuzu account mist</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Om game campatibiliteit te raporteren, moet je je yuzu account koppelen.&lt;br&gt;&lt;br/&gt; Om je yuzu account te koppelen, ga naar Emulatie &amp;gt; Configuratie &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo Bestand (%1);; Alle Bestanden (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Laad Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Fout tijdens het openen van het Amiibo gegevens bestand</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Kan Amiibo bestand &quot;%1&quot; niet lezen.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Fout tijdens het lezen van het Amiibo gegevens bestand</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Kan de volledige Amiibo gegevens niet lezen. Verwacht om %1 bytes te lezen, maar het is alleen mogelijk om %2 bytes te lezen.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Fout tijdens het laden van de Amiibo data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Kan de Amiibo gegevens niet laden.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Screenshot Vastleggen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>PNG afbeelding (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Snelheid: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Snelheid: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Game: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Frame: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>De game die je probeert te laden heeft extra bestanden nodig van je Switch voordat je het kan spelen. &lt;br/&gt;&lt;br/&gt;Voor meer informatie over het dumpen van deze bestanden, volg alsjeblieft onze wiki pagina: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Het dumpen van Systeem Archieven en de Gedeelde Lettertypen van een Switch console &lt;/a&gt;. &lt;br/&gt;&lt;br/&gt;Wil je terug gaan naar de game lijst? Verdergaan met de emulatie zal misschien gevolgen hebben als vastlopen, beschadigde opslag data, of andere problemen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>yuzu was niet in staat om de Switch systeem archieven te vinden. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>yuzu was niet in staat om de Switch systeem archieven te vinden. %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Systeem Archief Niet Gevonden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Systeem Archief Mist</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu was niet in staat om de Switch shared fonts te vinden. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Shared Fonts Niet Gevonden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Gedeelde Lettertypes Niet Gevonden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Fatale Fout</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu is een fatale fout tegengekomen, zie de log voor meer details. Voor meer informatie over toegang krijgen tot de log, zie de volgende pagina: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Hoe upload je een log bestand&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Zou je terug willen naar de game lijst? Doorgaan met emulatie kan resulteren in vastlapen, corrupte save gegevens, of andere problemen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Fatale Fout opgetreden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Bevestig Sleutel Herafleiding</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5064,37 +5113,37 @@ en optioneel maak backups.
Dit zal je automatisch gegenereerde sleutel bestanden verwijderen en de sleutel verkrijger module opnieuw starten</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5102,39 +5151,39 @@ on your system&apos;s performance.</source>
op je systeem&apos;s performatie.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Sleutels afleiden</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Selecteer RomFS Dump Doel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Selecteer welke RomFS je zou willen dumpen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Weet je zeker dat je yuzu wilt sluiten?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Weet je zeker dat je de emulatie wilt stoppen? Alle onopgeslagen voortgang will verloren gaan.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5511,12 +5560,12 @@ Screen.</source>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5525,11 +5574,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5551,112 +5601,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Screenshot Vastleggen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Volledig Scherm</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Laad Bestand</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5770,42 +5819,42 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Spelers</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation type="unfinished"/>
</message>
@@ -6132,7 +6181,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Verbonden</translation>
</message>
@@ -6154,7 +6203,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation type="unfinished"/>
</message>
@@ -6258,22 +6307,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6281,7 +6347,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
@@ -6336,7 +6402,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation type="unfinished"/>
</message>
@@ -6391,7 +6457,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[niet aangegeven]</translation>
</message>
@@ -6406,10 +6472,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Axis %1%2</translation>
</message>
@@ -6423,9 +6489,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[onbekend]</translation>
</message>
@@ -6590,15 +6656,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation type="unfinished"/>
</message>
@@ -6606,35 +6672,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[ongebruikt]</translation>
</message>
@@ -6675,7 +6741,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation type="unfinished"/>
</message>
diff --git a/dist/languages/pl.ts b/dist/languages/pl.ts
index 83b4d2b95..c4f75063a 100644
--- a/dist/languages/pl.ts
+++ b/dist/languages/pl.ts
@@ -95,78 +95,78 @@ p, li { white-space: pre-wrap; }
<translation>Wyślij Wiadomość</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation>Członkowie</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation>%1 dołączył/a</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation>%1 wyszedł/ła</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation>%1 został/a wyrzucony/a</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation>%1 został/a zbanowany/a</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation>%1 został/a odbanowany/a</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation>Wyświetl Profil</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation>Zablokuj Gracza</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation>Po zablokowaniu gracza nie będziesz otrzymywał od niego/jej wiadomości. &lt;br&gt;&lt;br&gt;Czy na pewno chcesz zablokować %1? </translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation>Wyrzuć</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation>Zbanuj</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation>Wyrzuć Gracza</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation>Na pewno chcesz &lt;b&gt;wyrzucić&lt;/b&gt; %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation>Zbanuj Gracza</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -758,200 +758,235 @@ Gdy ta opcja jest włączona, niedopasowanie jest uruchamiane tylko wtedy, gdy d
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Włącz namiastkę GDB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Port</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Logowanie</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Globalny filtr rejestrów</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Pokaż Log w konsoli</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Otwórz miejsce rejestrów</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Kiedy zaznaczony, maksymalny rozmiar logu wzrasta ze 100 MB do 1 GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Włącz Przedłużony Logging**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Linijka argumentu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Grafika</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Gdy zaznaczone, API grafiki przechodzi w wolniejszy tryb debugowania</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Włącz debugowanie grafiki</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>Gdy zaznaczone, włącza zrzucanie awarii Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Włącz Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation>Po zaznaczeniu, zrzuci wszystkie oryginalne shadery asemblera z pamięci podręcznej dysku shaderów albo gry, jeśli zostaną znalezione</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation>Zrzuć Shadery Gry</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>Gdy zaznaczone, wyłącza kompilator makr Just In Time. Włączenie tej opcji spowalnia działanie gier</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Wyłącz Makro JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>Po zaznaczeniu, yuzu będzie rejestrować statystyki dotyczące skompilowanej pamięci podręcznej.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>Włącz funkcję Feedbacku Shaderów</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>Gdy zaznaczone, używa shaderów bez zmian logicznych pętli</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>Wyłącz Zapętlanie sprawdzania bezpieczeństwa</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Debugowanie</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>Włącz Pełne Usługi Raportowania**</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
<source>Enable FS Access Log</source>
<translation>Włącz dziennik Dostępu FS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
+ <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
- <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>Włącz Pełne Usługi Raportowania**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Zaawansowane</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Tryb Kiosk (Quest)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Włącz Debugowanie CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Włącz potwierdzenia debugowania</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>Włącz Auto-Stub**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Wyłącz Aplet internetowy</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**To zresetuje się automatycznie po wyłączeniu yuzu.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1571,37 +1606,47 @@ Pozostaw tą funkcję włączoną, jeśli nie widać różnicy w wydajności.</t
<translation>Użyj Szybszego Czasu GPU (Hack)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Filtrowanie anizotropowe:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>Automatyczne</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Domyślne</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2093,7 +2138,7 @@ Pozostaw tą funkcję włączoną, jeśli nie widać różnicy w wydajności.</t
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Lewa gałka</translation>
</message>
@@ -2187,14 +2232,14 @@ Pozostaw tą funkcję włączoną, jeśli nie widać różnicy w wydajności.</t
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2213,7 +2258,7 @@ Pozostaw tą funkcję włączoną, jeśli nie widać różnicy w wydajności.</t
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Plus</translation>
</message>
@@ -2226,15 +2271,15 @@ Pozostaw tą funkcję włączoną, jeśli nie widać różnicy w wydajności.</t
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2291,231 +2336,236 @@ Pozostaw tą funkcję włączoną, jeśli nie widać różnicy w wydajności.</t
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Prawa gałka</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Wyczyść</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[nie ustawione]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Przycisk Toggle</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>Odwróć przycisk</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Przycisk Toggle</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Odwróć oś</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>Ustaw próg</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Wybierz wartość od 0% do 100%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation>Ustaw próg gyro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Przypisz Drążek Analogowy</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Po naciśnięciu OK, najpierw przesuń joystick w poziomie, a następnie w pionie.
Aby odwrócić osie, najpierw przesuń joystick pionowo, a następnie poziomo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Martwa strefa: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Zasięg Modyfikatora: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Para Joyconów</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Lewy Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Prawy Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Handheld</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>Kontroler GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>Kontroler NES/Pegasus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>Kontroler SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>Kontroler N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Sega Mega Drive</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Start / Pauza</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Lewa gałka</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-gałka</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Potrząśnij!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[oczekiwanie]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Nowy profil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Wpisz nazwę profilu:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Utwórz profil wejściowy</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>Podana nazwa profilu jest nieprawidłowa!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Nie udało się utworzyć profilu wejściowego &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Usuń profil wejściowy</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Nie udało się usunąć profilu wejściowego &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Załaduj profil wejściowy</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Nie udało się wczytać profilu wejściowego &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Zapisz profil wejściowy</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Nie udało się zapisać profilu wejściowego &quot;%1&quot;</translation>
</message>
@@ -2770,42 +2820,42 @@ Aby odwrócić osie, najpierw przesuń joystick pionowo, a następnie poziomo.</
<translation>Deweloper</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Dodatki</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Ogólne</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>System</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Grafika</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Zaaw. Grafika</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Dźwięk</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Właściwości</translation>
</message>
@@ -3517,47 +3567,47 @@ Aby odwrócić osie, najpierw przesuń joystick pionowo, a następnie poziomo.</
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Odczytuje dane wejściowe kontrolera ze skryptów takiego samego formatu jak skrypty TAS-nx.&lt;br/&gt; Jeśli chcesz otrzymać bardziej szczegółowe wyjaśnienie, wejdź na &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;stronę pomocy&lt;/span&gt;&lt;/a&gt; na stronie internetowej yuzu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>Aby sprawdzić jakie skróty sterują odtwarzaniem/nagrywaniem, odnieś się do ustawień Skrótów (Konfiguruj -&gt; Ogólne -&gt; Skróty Klawiszowe).</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>UWAGA: To jest funkcja eksperymentalna. Nie będzie odtwarzała skryptów co do klatki z teraźniejszą, nieperfekcyjną metodą synchronizacji.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Ustawienia</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>Włącz funkcje TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>Zapętlij skrypt</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>Zatrzymuj wykonanie w trakcie ładowania</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>Ścieżka Skryptu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Ścieżka</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3967,7 +4017,7 @@ Przeciągnij punkty, aby zmienić pozycję, lub kliknij dwukrotnie komórki tabe
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Zweryfikuj</translation>
</message>
@@ -4054,7 +4104,7 @@ Przeciągnij punkty, aby zmienić pozycję, lub kliknij dwukrotnie komórki tabe
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Nieokreślona</translation>
</message>
@@ -4069,17 +4119,36 @@ Przeciągnij punkty, aby zmienić pozycję, lub kliknij dwukrotnie komórki tabe
<translation>Token nie został zweryfikowany. Zmiana w Twoim tokenie nie została zapisana.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Weryfikowanie...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Weryfikowanie nieudane</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Weryfikowanie nieudane</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Weryfikacja nie powiodła się. Sprawdź, czy poprawnie podałeś swój token oraz czy działa twoje połączenie internetowe.</translation>
</message>
@@ -4148,12 +4217,12 @@ Przeciągnij punkty, aby zmienić pozycję, lub kliknij dwukrotnie komórki tabe
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation>Łączenie</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation>Połącz</translation>
</message>
@@ -4161,489 +4230,489 @@ Przeciągnij punkty, aby zmienić pozycję, lub kliknij dwukrotnie komórki tabe
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Dane anonimowe są gromadzone&lt;/a&gt; aby ulepszyć yuzu. &lt;br/&gt;&lt;br/&gt;Czy chcesz udostępnić nam swoje dane o użytkowaniu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Ładowanie apletu internetowego...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Wyłącz Aplet internetowy</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Wyłączanie web appletu może doprowadzić do nieokreślonych zachowań - wyłączyć applet należy jedynie grając w Super Mario 3D All-Stars. Na pewno chcesz wyłączyć web applet?
(Można go ponownie włączyć w ustawieniach debug.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>Ilość budowanych shaderów</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Obecnie wybrany mnożnik rozdzielczości.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Aktualna prędkość emulacji. Wartości większe lub niższe niż 100% wskazują, że emulacja działa szybciej lub wolniej niż Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Ile klatek na sekundę gra aktualnie wyświetla. To będzie się różnić w zależności od gry, od sceny do sceny.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Czas potrzebny do emulacji klatki na sekundę Switcha, nie licząc ograniczania klatek ani v-sync. Dla emulacji pełnej szybkości powinno to wynosić co najwyżej 16,67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Usuń Ostatnie pliki</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>&amp;Kontynuuj</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Pauza</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>yuzu jest w trakcie gry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>OSTRZEŻENIE! Nieaktualny format gry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Używasz zdekonstruowanego formatu katalogu ROM dla tej gry, który jest przestarzałym formatem, który został zastąpiony przez inne, takie jak NCA, NAX, XCI lub NSP. W zdekonstruowanych katalogach ROM brakuje ikon, metadanych i obsługi aktualizacji.&lt;br&gt;&lt;br&gt; Aby znaleźć wyjaśnienie różnych formatów Switch obsługiwanych przez yuzu,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt; sprawdź nasze wiki&lt;/a&gt;. Ta wiadomość nie pojawi się ponownie.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Błąd podczas wczytywania ROMu!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>Ten format ROMu nie jest wspierany.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Wystąpił błąd podczas inicjowania rdzenia wideo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu napotkał błąd podczas uruchamiania rdzenia wideo. Jest to zwykle spowodowane przestarzałymi sterownikami GPU, w tym zintegrowanymi. Więcej szczegółów znajdziesz w pliku log. Więcej informacji na temat dostępu do log-u można znaleźć na następującej stronie: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Jak przesłać plik log&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Błąd podczas wczytywania ROMu! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Postępuj zgodnie z&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu quickstart guide&lt;/a&gt; aby zrzucić ponownie swoje pliki.&lt;br&gt;Możesz odwołać się do wiki yuzu&lt;/a&gt;lub discord yuzu &lt;/a&gt; po pomoc.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Wystąpił nieznany błąd. Więcej informacji można znaleźć w pliku log.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Zapis danych</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Dane modów</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Błąd podczas otwarcia folderu %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Folder nie istnieje!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Błąd podczas otwierania przenośnej pamięci podręcznej Shaderów.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Nie udało się stworzyć ścieżki shaderów dla tego tytułu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Zawartość</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Łatka</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Usuń wpis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>Usunąć zainstalowaną grę %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>Pomyślnie usunięto</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>Pomyślnie usunięto zainstalowaną grę.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>Błąd podczas usuwania %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Gra nie jest zainstalowana w NAND i nie może zostać usunięta.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>Pomyślnie usunięto zainstalowaną łatkę.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>Brak zainstalowanych łatek dla tego tytułu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>Brak zainstalowanych DLC dla tego tytułu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Pomyślnie usunięto %1 zainstalowane DLC.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Usunąć Transferowalne Shadery OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Usunąć Transferowalne Shadery Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Usunąć Wszystkie Transferowalne Shadery?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>Usunąć niestandardową konfigurację gry?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Usuń plik</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Błąd podczas usuwania przenośnej pamięci podręcznej Shaderów.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>Pamięć podręczna Shaderów dla tego tytułu nie istnieje.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Pomyślnie usunięto przenośną pamięć podręczną Shaderów.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Nie udało się usunąć przenośnej pamięci Shaderów.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Błąd podczas usuwania Transferowalnych Shaderów</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Pomyślnie usunięto transferowalne shadery.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Nie udało się usunąć ścieżki transferowalnych shaderów.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Błąd podczas usuwania niestandardowej konfiguracji</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Niestandardowa konfiguracja nie istnieje dla tego tytułu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Pomyślnie usunięto niestandardową konfiguracje gry.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Nie udało się usunąć niestandardowej konfiguracji gry.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>Wypakowanie RomFS nieudane!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Wystąpił błąd podczas kopiowania plików RomFS lub użytkownik anulował operację.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Pełny</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Szkielet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Wybierz tryb zrzutu RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Proszę wybrać w jaki sposób chcesz, aby zrzut pliku RomFS został wykonany. &lt;br&gt;Pełna kopia ze wszystkimi plikami do nowego folderu, gdy &lt;br&gt;skielet utworzy tylko strukturę folderu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Nie ma wystarczająco miejsca w %1 aby wyodrębnić RomFS.
Zwolnij trochę miejsca, albo zmień ścieżkę zrzutu RomFs w Emulacja&gt; Konfiguruj&gt; System&gt; System Plików&gt; Źródło Zrzutu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Wypakowywanie RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Anuluj</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Wypakowanie RomFS zakończone pomyślnie!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>Operacja zakończona sukcesem.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Błąd podczas otwierania %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Wybierz folder...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Właściwości</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Właściwości tej gry nie mogły zostać załadowane.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Plik wykonywalny Switcha (%1);;Wszystkie pliki (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Załaduj plik...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Otwórz folder wypakowanego ROMu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Wybrano niewłaściwy folder</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Folder wybrany przez ciebie nie zawiera &apos;głownego&apos; pliku.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Instalacyjne pliki Switch&apos;a (*.nca *.nsp *.xci);;Archiwum zawartości Nintendo (*.nca);;Pakiet poddany Nintendo (*.nsp);;Obraz z kartridża NX (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Zainstaluj pliki</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>1 plik został</numerusform><numerusform>%n plików zostało</numerusform><numerusform>%n plików zostało</numerusform><numerusform>%n plików zostało</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Instalowanie pliku &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Wynik instalacji</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Aby uniknąć ewentualnych konfliktów, odradzamy użytkownikom instalowanie gier na NAND.
Proszę, używaj tej funkcji tylko do instalowania łatek i DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>1 nowy plik został zainstalowany
@@ -4653,424 +4722,404 @@ Proszę, używaj tej funkcji tylko do instalowania łatek i DLC.</translation>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>1 plik został nadpisany</numerusform><numerusform>%n plików zostało nadpisane</numerusform><numerusform>%n plików zostało nadpisane</numerusform><numerusform>%n plików zostało nadpisane</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>1 pliku nie udało się zainstalować</numerusform><numerusform>%n plików nie udało się zainstalować</numerusform><numerusform>%n plików nie udało się zainstalować</numerusform><numerusform>%n plików nie udało się zainstalować</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Aplikacja systemowa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Archiwum systemu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Aktualizacja aplikacji systemowej</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Paczka systemowa (Typ A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Paczka systemowa (Typ B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Gra</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Aktualizacja gry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>Dodatek do gry</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Tytuł Delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Wybierz typ instalacji NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Wybierz typ tytułu, do którego chcesz zainstalować ten NCA, jako:
(W większości przypadków domyślna &quot;gra&quot; jest w porządku.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Instalacja nieudana</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Typ tytułu wybrany dla NCA jest nieprawidłowy.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Nie znaleziono pliku</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Nie znaleziono pliku &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Brakuje konta Yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Aby przesłać test zgodności gry, musisz połączyć swoje konto yuzu.&lt;br&gt;&lt;br/&gt; Aby połączyć swoje konto yuzu, przejdź do opcji Emulacja &amp;gt; Konfiguracja &amp;gt; Sieć.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Błąd otwierania adresu URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Nie można otworzyć adresu URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>Nagrywanie TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>Nadpisać plik gracza 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>Wykryto nieprawidłową konfigurację</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Nie można używać kontrolera handheld w trybie zadokowanym. Zostanie wybrany kontroler Pro.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>Błąd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation>Ta gra nie szuka amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation>Amiibo zostało &quot;zdjęte&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Plik Amiibo (%1);;Wszyskie pliki (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Załaduj Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Błąd otwarcia pliku danych Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Nie można otworzyć pliku Amiibo &quot;%1&quot; do odczytu.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Błąd podczas odczytu pliku danych Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Nie można w pełni odczytać danych Amiibo. Oczekiwano odczytu %1 bajtów, ale był on w stanie odczytać tylko %2 bajty.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Błąd podczas ładowania pliku danych Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Nie można załadować danych Amiibo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Zrób zrzut ekranu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>Obrazek PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>Status TAS: Działa %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>Status TAS: Nagrywa %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>Status TAS: Bezczynny %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>Status TAS: Niepoprawny</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>&amp;Wyłącz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>Przestań N&amp;agrywać</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>N&amp;agraj</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Budowanie shadera</numerusform><numerusform>Budowanie: %n shaderów</numerusform><numerusform>Budowanie: %n shaderów</numerusform><numerusform>Budowanie: %n shaderów</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Skala: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Prędkość: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Prędkość: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Gra: %1 FPS (Odblokowane)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Gra: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Klatka: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMALNE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU WYSOKIE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU EKSTREMALNE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>BŁĄD GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation>TRYB ZADOKOWANY</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation>TRYB PRZENOŚNY</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>NAJBLIŻSZY</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>BILINEARNY</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>BIKUBICZNY</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>GAUSSIAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>BEZ AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>Gra, którą próbujesz wczytać, wymaga dodatkowych plików z Switch&apos;a, które zostaną zrzucone przed graniem.&lt;br/&gt;&lt;br/&gt; Aby uzyskać więcej informacji na temat wyrzucania tych plików, odwiedź następującą stronę wiki:&lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt; Zrzut archiw systemu i udostępnionych czcionek z konsoli Nintendo Switch&lt;/a&gt;. &lt;br/&gt;&lt;br/&gt;Czy chcesz wrócić do listy gier? Kontynuacja emulacji może spowodować awarie, uszkodzone dane zapisu lub inne błędy.
</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>yuzu nie był w stanie znaleźć archiwum systemu Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>yuzu nie był w stanie znaleźć archiwum systemu Switch. %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Archiwum systemu nie znalezione.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Brak archiwum systemowego</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu nie był w stanie zlokalizować czcionek Switch&apos;a. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Czcionki nie zostały znalezione</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Brak wspólnej czcionki</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Fatalny błąd</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu napotkał błąd, proszę zobaczyć log po więcej szczegółów. Aby uzyskać więcej informacji na temat uzyskiwania dostępu do pliku log, zobacz następującą stronę: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Jak przesłać plik log&lt;/a&gt;?&lt;br/&gt;&lt;br/&gt; Czy chcesz wrócić do listy gier? Kontynuacja emulacji może spowodować awarie, uszkodzone dane zapisu lub inne błędy.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Wystąpił błąd krytyczny</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Potwierdź ponowną aktywacje klucza</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5087,37 +5136,37 @@ i opcjonalnie tworzyć kopie zapasowe.
Spowoduje to usunięcie wygenerowanych automatycznie plików kluczy i ponowne uruchomienie modułu pochodnego klucza.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>Brakujące bezpieczniki</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation> - Brak BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - Brak BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation> - Brak PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>Brak komponentów wyprowadzania</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Brakuje elementów, które mogą uniemożliwić zakończenie wyprowadzania kluczy. &lt;br&gt;Postępuj zgodnie z &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu quickstart guide&lt;/a&gt; aby zdobyć wszystkie swoje klucze i gry.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5126,39 +5175,39 @@ Zależnie od tego może potrwać do minuty
na wydajność twojego systemu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Wyprowadzanie kluczy...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Wybierz cel zrzutu RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Proszę wybrać RomFS, jakie chcesz zrzucić.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Czy na pewno chcesz zamknąć yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Czy na pewno chcesz zatrzymać emulację? Wszystkie niezapisane postępy zostaną utracone.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5540,12 +5589,12 @@ startowy.</translation>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>Błąd</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5554,11 +5603,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation>Wycisz/Odcisz Audio</translation>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5580,112 +5630,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Zrób zrzut ekranu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation>Kontynuuj/Zatrzymaj Emulację</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation>Wyłącz Pełny Ekran</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation>Wyjdź z yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Pełny ekran</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Załaduj plik...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation>Załaduj/Usuń Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation>Zrestartuj Emulację</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation>Zatrzymaj Emulację</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5800,42 +5849,42 @@ Debug Message: </source>
<translation>Odśwież Lobby</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation>Aby dołączyć, potrzebne jest hasło</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation>Hasło:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation>Nazwa Pokoju</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation>Preferowana Gra</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation>Host</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Gracze</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation>Odświeżam</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation>Odśwież listę</translation>
</message>
@@ -6162,7 +6211,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Połączony</translation>
</message>
@@ -6184,7 +6233,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation>Otrzymano nowe wiadomości</translation>
</message>
@@ -6289,22 +6338,39 @@ They may have left the room.</source>
Możliwe, że opuścił/a pokój.</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation>Wyjdź z Pokoju Multiplayer</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation>Zamierzasz zamknąć pokój multiplayer. Wszystkie połączenia zostaną zamknięte.</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation>Rozłącz</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation>Wychodzisz z pokoju multiplayer. Wszystkie połączenia zostaną zamknięte.</translation>
</message>
@@ -6312,7 +6378,7 @@ Możliwe, że opuścił/a pokój.</translation>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>Błąd</translation>
</message>
@@ -6371,7 +6437,7 @@ p, li { white-space: pre-wrap; }
<translation>%1 gra w %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation>Nie gra w żadną grę</translation>
</message>
@@ -6426,7 +6492,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[nie ustawione]</translation>
</message>
@@ -6441,10 +6507,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Oś %1%2</translation>
</message>
@@ -6458,9 +6524,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[nieznane]</translation>
</message>
@@ -6625,15 +6691,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[niepoprawne]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation>%1%2Drążek %3</translation>
</message>
@@ -6641,35 +6707,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation>%1%2Oś %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation>%1%2Oś %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2Ruch %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2Przycisk %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[nieużywane]</translation>
</message>
@@ -6710,7 +6776,7 @@ p, li { white-space: pre-wrap; }
<translation>Dodatkowe</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/languages/pt_BR.ts b/dist/languages/pt_BR.ts
index 40a8a4cf6..bee6aa5b9 100644
--- a/dist/languages/pt_BR.ts
+++ b/dist/languages/pt_BR.ts
@@ -36,7 +36,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="130"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Site&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Código fonte&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contribuidores&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Licença&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="146"/>
@@ -82,95 +82,97 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="14"/>
<source>Room Window</source>
- <translation type="unfinished"/>
+ <translation>Janela da sala</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="40"/>
<source>Send Chat Message</source>
- <translation type="unfinished"/>
+ <translation>Enviar mensagem no bate-papo</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="47"/>
<source>Send Message</source>
- <translation type="unfinished"/>
+ <translation>Enviar mensagem</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
- <translation type="unfinished"/>
+ <translation>Membros</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
- <translation type="unfinished"/>
+ <translation>%1 entrou</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
- <translation type="unfinished"/>
+ <translation>%1 saiu</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
- <translation type="unfinished"/>
+ <translation>%1 foi expulso(a)</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
- <translation type="unfinished"/>
+ <translation>%1 foi banido(a)</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
- <translation type="unfinished"/>
+ <translation>%1 foi desbanido(a)</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
- <translation type="unfinished"/>
+ <translation>Ver perfil</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
- <translation type="unfinished"/>
+ <translation>Bloquear jogador</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
- <translation type="unfinished"/>
+ <translation>Quando bloqueia um jogador, você não receberá mais mensagens dele.&lt;br&gt;&lt;br&gt;Você deseja mesmo bloquear %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
- <translation type="unfinished"/>
+ <translation>Expulsar</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
- <translation type="unfinished"/>
+ <translation>Banir</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
- <translation type="unfinished"/>
+ <translation>Expulsar jogador</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
- <translation type="unfinished"/>
+ <translation>Você deseja mesmo &lt;b&gt;expulsar&lt;/b&gt; %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
- <translation type="unfinished"/>
+ <translation>Banir jogador</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
- <translation type="unfinished"/>
+ <translation>Você deseja mesmo &lt;b&gt;expulsar e banir&lt;/b&gt; %1?
+
+Isto banirá tanto o nome de usuário do fórum como o endereço IP.</translation>
</message>
</context>
<context>
@@ -178,22 +180,22 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="14"/>
<source>Room Window</source>
- <translation type="unfinished"/>
+ <translation>Janela da sala</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="27"/>
<source>Room Description</source>
- <translation type="unfinished"/>
+ <translation>Descrição da sala</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="47"/>
<source>Moderation...</source>
- <translation type="unfinished"/>
+ <translation>Moderação...</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="57"/>
<source>Leave Room</source>
- <translation type="unfinished"/>
+ <translation>Sair da sala</translation>
</message>
</context>
<context>
@@ -206,12 +208,12 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="87"/>
<source>Disconnected</source>
- <translation type="unfinished"/>
+ <translation>Desconectado</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="100"/>
<source>%1 (%2/%3 members) - connected</source>
- <translation type="unfinished"/>
+ <translation>%1 (%2/%3 membros) - conectado</translation>
</message>
</context>
<context>
@@ -339,7 +341,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_audio.ui" line="42"/>
<source>Output Device</source>
- <translation type="unfinished"/>
+ <translation>Dispositivo de saída</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_audio.ui" line="56"/>
@@ -378,37 +380,37 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="14"/>
<source>Configure Infrared Camera</source>
- <translation type="unfinished"/>
+ <translation>Configurar câmera infravermelha</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="26"/>
<source>Select where the image of the emulated camera comes from. It may be a virtual camera or a real camera.</source>
- <translation type="unfinished"/>
+ <translation>Selecione de onde vem a imagem da câmera emulada. Pode ser uma câmera virtual ou uma câmera real.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="52"/>
<source>Camera Image Source:</source>
- <translation type="unfinished"/>
+ <translation>Origem da imagem da câmera:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="71"/>
<source>Input device:</source>
- <translation type="unfinished"/>
+ <translation>Dispositivo de entrada:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="96"/>
<source>Preview</source>
- <translation type="unfinished"/>
+ <translation>Prévia</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="108"/>
<source>Resolution: 320*240</source>
- <translation type="unfinished"/>
+ <translation>Resolução: 320*240</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="115"/>
<source>Click to preview</source>
- <translation type="unfinished"/>
+ <translation>Clique para pré-visualizar</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="140"/>
@@ -769,200 +771,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation>Depurador</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Ativar GDB stub</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Porta:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Registros de depuração</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Filtro global de registros</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Mostrar registro no console</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Abrir local dos registros</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Quando ativado, o tamanho máximo do arquivo de registro aumenta de 100 MB para 1 GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Ativar registros avançados**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Linha de argumentos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Gráficos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Quando ativado, a API gráfica entra em um modo de depuração mais lento.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Ativar depuração de gráficos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>Quando ativado, ativa a extração de registros de travamento do Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Ativar Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation>Se selecionado, extrai todos os shaders originários do cache do disco ou do jogo conforme encontrá-los.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation>Descarregar shaders do jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation>Quando marcada, essa opção irá extrair todos os macro programas da GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation>Extrair macros Maxwell</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>Quando ativado, desativa o macro compilador Just In Time. Ativar isto faz os jogos rodarem mais lentamente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Desativar macro JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>Quando ativado, o yuzu registrará estatísticas sobre o cache de pipeline compilado</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>Ativar Feedback de Shaders</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>Quando ativado, executa shaders sem mudanças de lógica de loop</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>Desativar verificação de segurança de loops</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Depuração</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>Ativar serviços de relatório detalhado**</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
<source>Enable FS Access Log</source>
<translation>Ativar acesso de registro FS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
+ <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
- <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>Ativar serviços de relatório detalhado**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Avançado</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Modo quiosque (Quest)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Ativar depuração de CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Ativar asserções de depuração</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>Ativar auto-esboço**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation>Ativar todos os tipos de controles</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Desativar o applet da web</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Isto será restaurado automaticamente assim que o yuzu for fechado.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1581,37 +1618,47 @@ This would ban both their forum username and their IP address.</source>
<translation>Usar tempo de resposta rápido da GPU (Hack)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Filtragem anisotrópica:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>Automático</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Padrão</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2103,7 +2150,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Analógico esquerdo</translation>
</message>
@@ -2197,14 +2244,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2223,7 +2270,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Mais</translation>
</message>
@@ -2236,15 +2283,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2301,231 +2348,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Analógico direito</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Limpar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[não definido]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Alternar pressionamento do botão</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>Inverter botão</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Alternar pressionamento do botão</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Inverter eixo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>Definir limite</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Escolha um valor entre 0% e 100%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation>Definir limite do giroscópio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Mapear analógico</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Após pressionar OK, mova o seu direcional analógico primeiro horizontalmente e depois verticalmente.
Para inverter os eixos, mova seu analógico primeiro verticalmente e depois horizontalmente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation>Eixo central</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Zona morta: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Alcance de modificador: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Par de Joycons</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Joycon Esquerdo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Joycon Direito</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Portátil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>Controle de GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>Controle NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>Controle SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>Controle N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Mega Drive</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Iniciar / Pausar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Direcional de controle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Balance!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[esperando]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Novo perfil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Insira um nome para o perfil:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Criar perfil de controle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>O nome de perfil inserido não é válido!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Falha ao criar o perfil de controle &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Excluir perfil de controle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Falha ao excluir o perfil de controle &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Carregar perfil de controle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Falha ao carregar o perfil de controle &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Salvar perfil de controle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Falha ao salvar o perfil de controle &quot;%1&quot;</translation>
</message>
@@ -2780,42 +2832,42 @@ Para inverter os eixos, mova seu analógico primeiro verticalmente e depois hori
<translation>Desenvolvedor</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Adicionais</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Geral</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Gráficos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Gráf. avançados</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Áudio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Propriedades</translation>
</message>
@@ -3527,47 +3579,47 @@ Para inverter os eixos, mova seu analógico primeiro verticalmente e depois hori
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Lê entradas de controle a partir de scripts no mesmo formato que TAS-nx. &lt;br/&gt;Para uma explicação mais detalhada, por favor consulte a &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;página de ajuda&lt;/span&gt;&lt;/a&gt; no website do yuzu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>Para checar que atalhos controlam rodar/gravar, por favor refira-se às Teclas de atalhos (Configurar -&gt; Geral -&gt; Teclas de atalhos)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>ATENÇÃO: Este é um recurso experimental. &lt;br/&gt;Não irá rodar os scrips em quadros perfeitos com o atual, imperfeito método de sincronização. </translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Configurações</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>Ativar funcionalidades TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>Repetir script em loop</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>Pausar execução durante carregamentos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>Diretório do script</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Caminho</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3977,7 +4029,7 @@ Mova os pontos para mudar a posição, ou clique duas vezes nas células da tabe
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Verificar</translation>
</message>
@@ -4064,7 +4116,7 @@ Mova os pontos para mudar a posição, ou clique duas vezes nas células da tabe
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Não especificado</translation>
</message>
@@ -4079,17 +4131,36 @@ Mova os pontos para mudar a posição, ou clique duas vezes nas células da tabe
<translation>O token não foi verificado. A alteração no seu token não foi salva.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Verificando...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Falha na verificação</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Falha na verificação</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Falha na verificação. Verifique se o seu token foi inserido corretamente e se a sua conexão à internet está funcionando.</translation>
</message>
@@ -4158,12 +4229,12 @@ Mova os pontos para mudar a posição, ou clique duas vezes nas células da tabe
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation type="unfinished"/>
</message>
@@ -4171,488 +4242,488 @@ Mova os pontos para mudar a posição, ou clique duas vezes nas células da tabe
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Dados anônimos são recolhidos&lt;/a&gt; para ajudar a melhorar o yuzu. &lt;br/&gt;&lt;br/&gt;Gostaria de compartilhar os seus dados de uso conosco?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Carregando applet web...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Desativar o applet da web</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>A desativação do applet da web pode causar comportamento inesperado e deve apenas ser usada com Super Mario 3D All-Stars. Você deseja mesmo desativar o applet da web?
(Ele pode ser reativado nas configurações de depuração.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>A quantidade de shaders sendo construídos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>O atualmente multiplicador de escala de resolução selecionado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Velocidade atual de emulação. Valores maiores ou menores que 100% indicam que a emulação está rodando mais rápida ou lentamente que em um Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Quantos quadros por segundo o jogo está exibindo atualmente. Isto irá variar de jogo para jogo e cena para cena.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tempo que leva para emular um quadro do Switch, sem considerar o limitador de taxa de quadros ou a sincronização vertical. Um valor menor ou igual a 16.67 ms indica que a emulação está em velocidade plena.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Limpar arquivos recentes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>&amp;Continuar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Pausar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>yuzu está rodando um jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Aviso - formato de jogo desatualizado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Você está usando neste jogo o formato de ROM desconstruída e extraída em uma pasta, que é um formato desatualizado que foi substituído por outros, como NCA, NAX, XCI ou NSP. Pastas desconstruídas de ROMs não possuem ícones, metadados e suporte a atualizações.&lt;br&gt;&lt;br&gt;Para saber mais sobre os vários formatos de ROMs de Switch compatíveis com o yuzu, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;confira a nossa wiki&lt;/a&gt;. Esta mensagem não será exibida novamente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Erro ao carregar a ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>O formato da ROM não é suportado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Ocorreu um erro ao inicializar o núcleo de vídeo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu encontrou um erro enquanto rodando o núcleo de vídeo. Normalmente isto é causado por drivers de GPU desatualizados, incluindo integrados. Por favor veja o registro para mais detalhes. Para mais informações em acesso ao registro por favor veja a seguinte página: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Como fazer envio de arquivo de registro&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Erro ao carregar a ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Por favor, siga &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;o guia de início rápido&lt;/a&gt; para reextrair os seus arquivos.&lt;br&gt;Você pode consultar a wiki do yuzu&lt;/a&gt; ou o Discord do yuzu&lt;/a&gt; para obter ajuda.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Ocorreu um erro desconhecido. Consulte o registro para mais detalhes.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Dados de jogos salvos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Dados de mods</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Erro ao abrir a pasta %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>A pasta não existe!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Erro ao abrir o cache de shaders transferível</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Falha ao criar o diretório de cache de shaders para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Conteúdo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Atualização</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Remover item</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>Remover o jogo instalado %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>Removido com sucesso</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>O jogo base foi removido com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>Erro ao remover %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>O jogo base não está instalado na NAND e não pode ser removido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>A atualização instalada foi removida com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>Não há nenhuma atualização instalada para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>Não há nenhum DLC instalado para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>%1 DLC(s) instalados foram removidos com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Apagar o cache de shaders transferível do OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Apagar o cache de shaders transferível do Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Apagar todos os caches de shaders transferíveis?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>Remover configurações customizadas do jogo?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Remover arquivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Erro ao remover cache de shaders transferível</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>Não existe um cache de shaders para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>O cache de shaders transferível foi removido com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Falha ao remover o cache de shaders transferível.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Erro ao remover os caches de shaders transferíveis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Os caches de shaders transferíveis foram removidos com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Falha ao remover o diretório do cache de shaders transferível.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Erro ao remover as configurações customizadas do jogo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Não há uma configuração customizada para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>As configurações customizadas do jogo foram removidas com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Falha ao remover as configurações customizadas do jogo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>Falha ao extrair RomFS!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Houve um erro ao copiar os arquivos RomFS ou o usuário cancelou a operação.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Extração completa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Apenas estrutura</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Selecione o modo de extração do RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Selecione a forma como você gostaria que o RomFS seja extraído.&lt;br&gt;&quot;Extração completa&quot; copiará todos os arquivos para a nova pasta, enquanto que &lt;br&gt;&quot;Apenas estrutura&quot; criará apenas a estrutura de pastas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Não há espaço suficiente em %1 para extrair o RomFS. Por favor abra espaço ou selecione um diretório diferente em Emulação &gt; Configurar &gt; Sistema &gt; Sistema de arquivos &gt; Extrair raiz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Extraindo RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Cancelar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Extração do RomFS concluida!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>A operação foi concluída com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Erro ao abrir %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Selecionar pasta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Propriedades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>As propriedades do jogo não puderam ser carregadas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Executável do Switch (%1);;Todos os arquivos (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Carregar arquivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Abrir pasta da ROM extraída</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Pasta inválida selecionada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>A pasta que você selecionou não contém um arquivo &apos;main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Arquivo de Switch instalável (*.nca *.nsp *.xci);; Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Instalar arquivos</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n arquivo restante</numerusform><numerusform>%n arquivo(s) restante(s)</numerusform><numerusform>%n arquivo(s) restante(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Instalando arquivo &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Resultados da instalação</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Para evitar possíveis conflitos, desencorajamos que os usuários instalem os jogos base na NAND.
Por favor, use esse recurso apenas para instalar atualizações e DLCs.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n arquivo(s) instalado(s)
@@ -4661,7 +4732,7 @@ Por favor, use esse recurso apenas para instalar atualizações e DLCs.</transla
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n arquivo(s) sobrescrito(s)
@@ -4670,7 +4741,7 @@ Por favor, use esse recurso apenas para instalar atualizações e DLCs.</transla
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n arquivo(s) não instalado(s)
@@ -4679,411 +4750,391 @@ Por favor, use esse recurso apenas para instalar atualizações e DLCs.</transla
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Aplicativo do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Arquivo do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Atualização de aplicativo do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Pacote de firmware (tipo A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Pacote de firmware (tipo B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Atualização de jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>DLC de jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Título delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Selecione o tipo de instalação do NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Selecione o tipo de título como o qual você gostaria de instalar este NCA:
(Na maioria dos casos, o padrão &apos;Jogo&apos; serve bem.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Falha ao instalar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>O tipo de título que você selecionou para o NCA é inválido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Arquivo não encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Arquivo &quot;%1&quot; não encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Conta do yuzu faltando</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Para enviar um caso de teste de compatibilidade de jogo, você precisa entrar com a sua conta do yuzu.&lt;br&gt;&lt;br/&gt;Para isso, vá para Emulação &amp;gt; Configurar... &amp;gt; Rede.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Erro ao abrir URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Não foi possível abrir o URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>Gravando TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>Sobrescrever arquivo do jogador 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>Configuração inválida detectada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>O controle portátil não pode ser usado no modo encaixado na base. O Pro Controller será selecionado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>Erro</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation>O jogo atual não está procurando amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation>O amiibo atual foi removido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Arquivo Amiibo (%1);; Todos os arquivos (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Carregar Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Erro ao abrir arquivo de dados do Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Não foi possível abrir o arquivo de Amiibo &quot;%1&quot; para leitura.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Erro ao ler arquivo de dados de Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Não foi possível ler completamente os dados do Amiibo. O yuzu esperava ler %1 bytes, mas foi capaz de ler apenas %2 bytes.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Erro ao carregar dados do Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Não foi possível carregar os dados do Amiibo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Capturar tela</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>Imagem PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>Situação TAS: Rodando %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>Situação TAS: Gravando %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>Situação TAS: Repouso %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>Situação TAS: Inválido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>&amp;Parar de rodar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Iniciar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>Parar G&amp;ravação</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>G&amp;ravação</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Compilando: %n shader(s)</numerusform><numerusform>Compilando: %n shader(s)</numerusform><numerusform>Compilando: %n shader(s)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Escala: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Velocidade: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Velocidade: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Jogo: %1 FPS (Desbloqueado)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Jogo: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Quadro: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU ALTA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU EXTREMA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>ERRO DE GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>VIZINHO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>BILINEAR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>BICÚBICO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>GAUSSIANO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>Sem AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>O jogo que você está tentando carregar precisa que arquivos adicionais do seu Switch sejam extraídos antes de jogá-lo.&lt;br/&gt;&lt;br/&gt;Para saber mais sobre como extrair esses arquivos, visite a seguinte página da wiki: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Extraindo arquivos de sistema e fontes compartilhadas de um Switch&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt; Gostaria de voltar para a lista de jogos? Continuar com a emulação pode resultar em travamentos, dados salvos corrompidos ou outros problemas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>O yuzu não foi capaz de encontrar um arquivo de sistema do Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>O yuzu não foi capaz de encontrar um arquivo de sistema do Switch. %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Arquivo do sistema não encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Arquivo de sistema faltando</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>O yuzu não foi capaz de encontrar as fontes compartilhadas do Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Fontes compartilhadas não encontradas</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Fonte compartilhada faltando</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Erro fatal</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>O yuzu encontrou um erro fatal. Consulte o registro para mais detalhes. Para mais informações sobre como acessar o registro, consulte a seguinte página: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Como enviar o arquivo de registro&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Gostaria de voltar para a lista de jogos? Continuar com a emulação pode resultar em travamentos, dados salvos corrompidos ou outros problemas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Erro fatal encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Confirmar rederivação de chave</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5100,37 +5151,37 @@ e opcionalmente faça cópias de segurança.
Isto excluirá o seus arquivos de chaves geradas automaticamente, e reexecutar o módulo de derivação de chaves.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>Faltando fusíveis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation> - Faltando BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - Faltando BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation> - Faltando PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>Faltando componentes de derivação</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Chaves de encriptação faltando. &lt;br&gt;Por favor, siga &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;o guia de início rápido&lt;/a&gt; para extrair suas chaves, firmware e jogos. &lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5139,39 +5190,39 @@ Isto pode demorar até um minuto, dependendo
do desempenho do seu sistema.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Derivando chaves</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Selecionar alvo de extração do RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Selecione qual RomFS você quer extrair.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Você deseja mesmo fechar o yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Deseja mesmo parar a emulação? Qualquer progresso não salvo será perdido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5527,7 +5578,7 @@ tela inicial do jogo.</translation>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="139"/>
<source>Room Description</source>
- <translation type="unfinished"/>
+ <translation>Descrição da sala</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="153"/>
@@ -5553,12 +5604,12 @@ tela inicial do jogo.</translation>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>Erro</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5567,11 +5618,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5593,112 +5645,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Capturar tela</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Tela cheia</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Carregar arquivo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5813,42 +5864,42 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Jogadores</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation type="unfinished"/>
</message>
@@ -6018,7 +6069,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/main.ui" line="270"/>
<source>Leave Room</source>
- <translation type="unfinished"/>
+ <translation>Sair da sala</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="275"/>
@@ -6175,7 +6226,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Conectado</translation>
</message>
@@ -6197,7 +6248,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation type="unfinished"/>
</message>
@@ -6301,22 +6352,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
- <source>Leave Room</source>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
+ <source>Leave Room</source>
+ <translation>Sair da sala</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6324,7 +6392,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>Erro</translation>
</message>
@@ -6383,7 +6451,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation type="unfinished"/>
</message>
@@ -6438,7 +6506,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[não definido]</translation>
</message>
@@ -6453,10 +6521,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Eixo %1%2</translation>
</message>
@@ -6470,9 +6538,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[desconhecido]</translation>
</message>
@@ -6637,15 +6705,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[inválido]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation>%1%2Direcional %3</translation>
</message>
@@ -6653,35 +6721,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation>%1%2Eixo %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation>%1%2Eixo %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2Movimentação %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2Botão %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[não utilizado]</translation>
</message>
@@ -6722,7 +6790,7 @@ p, li { white-space: pre-wrap; }
<translation>Extra</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/languages/pt_PT.ts b/dist/languages/pt_PT.ts
index 74d7656bd..525f0e984 100644
--- a/dist/languages/pt_PT.ts
+++ b/dist/languages/pt_PT.ts
@@ -36,7 +36,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="130"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>Site | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Código fonte | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contribuidores&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Licença&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="146"/>
@@ -82,95 +82,97 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="14"/>
<source>Room Window</source>
- <translation type="unfinished"/>
+ <translation>Janela da sala</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="40"/>
<source>Send Chat Message</source>
- <translation type="unfinished"/>
+ <translation>Enviar mensagem</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="47"/>
<source>Send Message</source>
- <translation type="unfinished"/>
+ <translation>Enviar mensagem</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
- <translation type="unfinished"/>
+ <translation>Membros</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
- <translation type="unfinished"/>
+ <translation>%1 entrou</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
- <translation type="unfinished"/>
+ <translation>%1 saiu</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
- <translation type="unfinished"/>
+ <translation>%1 foi expulso(a)</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
- <translation type="unfinished"/>
+ <translation>%1 foi banido(a)</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
- <translation type="unfinished"/>
+ <translation>%1 foi desbanido(a)</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
- <translation type="unfinished"/>
+ <translation>Ver perfil</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
- <translation type="unfinished"/>
+ <translation>Bloquear jogador</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
- <translation type="unfinished"/>
+ <translation>Quando bloqueia um jogador, você não receberá mais mensagens dele.&lt;br&gt;&lt;br&gt;Você deseja mesmo bloquear %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
- <translation type="unfinished"/>
+ <translation>Expulsar</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
- <translation type="unfinished"/>
+ <translation>Banir</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
- <translation type="unfinished"/>
+ <translation>Expulsar jogador</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
- <translation type="unfinished"/>
+ <translation>Você deseja mesmo &lt;b&gt;expulsar&lt;/b&gt; %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
- <translation type="unfinished"/>
+ <translation>Banir jogador</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
- <translation type="unfinished"/>
+ <translation>Você deseja mesmo &lt;b&gt;expulsar e banir&lt;/b&gt; %1?
+
+Isto banirá tanto o nome de usuário do fórum como o endereço IP.</translation>
</message>
</context>
<context>
@@ -178,22 +180,22 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="14"/>
<source>Room Window</source>
- <translation type="unfinished"/>
+ <translation>Janela da sala</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="27"/>
<source>Room Description</source>
- <translation type="unfinished"/>
+ <translation>Descrição da sala</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="47"/>
<source>Moderation...</source>
- <translation type="unfinished"/>
+ <translation>Moderação...</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="57"/>
<source>Leave Room</source>
- <translation type="unfinished"/>
+ <translation>Sair da sala</translation>
</message>
</context>
<context>
@@ -206,12 +208,12 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="87"/>
<source>Disconnected</source>
- <translation type="unfinished"/>
+ <translation>Desconectado</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="100"/>
<source>%1 (%2/%3 members) - connected</source>
- <translation type="unfinished"/>
+ <translation>%1 (%2/%3 membros) - conectado</translation>
</message>
</context>
<context>
@@ -339,7 +341,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_audio.ui" line="42"/>
<source>Output Device</source>
- <translation type="unfinished"/>
+ <translation>Dispositivo de saída</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_audio.ui" line="56"/>
@@ -378,37 +380,37 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="14"/>
<source>Configure Infrared Camera</source>
- <translation type="unfinished"/>
+ <translation>Configurar câmera infravermelha</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="26"/>
<source>Select where the image of the emulated camera comes from. It may be a virtual camera or a real camera.</source>
- <translation type="unfinished"/>
+ <translation>Selecione de onde vem a imagem da câmera emulada. Pode ser uma câmera virtual ou uma câmera real.</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="52"/>
<source>Camera Image Source:</source>
- <translation type="unfinished"/>
+ <translation>Origem da imagem da câmera:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="71"/>
<source>Input device:</source>
- <translation type="unfinished"/>
+ <translation>Dispositivo de entrada:</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="96"/>
<source>Preview</source>
- <translation type="unfinished"/>
+ <translation>Prévia</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="108"/>
<source>Resolution: 320*240</source>
- <translation type="unfinished"/>
+ <translation>Resolução: 320*240</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="115"/>
<source>Click to preview</source>
- <translation type="unfinished"/>
+ <translation>Clique para pré-visualizar</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="140"/>
@@ -759,200 +761,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation>Depurador</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Activar GDB Stub</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Porta:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Entrando</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Filtro de registro global</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Mostrar Relatório na Consola</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Abrir a localização do registro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Quando ativado, o tamanho máximo do registo aumenta de 100 MB para 1 GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Ativar registros avançados**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Argumentos String</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Gráficos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Quando ativado, a API gráfica entra em um modo de depuração mais lento.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Activar Depuração Gráfica</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>Quando ativado, ativa a extração de registros de travamento do Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Ativar Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation>Se selecionado, descarrega todos os shaders originários do cache do disco ou do jogo conforme encontrá-los.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation>Descarregar shaders do jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation>Quando marcada, essa opção irá despejar todos os macro programas da GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation>Despejar macros Maxwell</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>Quando ativado, desativa o macro compilador Just In Time. Ativar isto faz os jogos rodarem mais lentamente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Desactivar Macro JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>Quando ativado, o yuzu registrará estatísticas sobre o cache de pipeline compilado</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>Ativar Feedback de Shaders</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>Quando ativado, executa shaders sem mudanças de lógica de loop</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>Desativar verificação de segurança de loops</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Depuração</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>Ativar serviços de relatório detalhado**</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
<source>Enable FS Access Log</source>
<translation>Ativar acesso de registro FS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
+ <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
- <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>Ativar serviços de relatório detalhado**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Avançado</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Modo Quiosque (Quest)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Ativar depuração de CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Ativar asserções de depuração</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>Ativar auto-esboço**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation>Ativar todos os tipos de controles</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Desativar Web Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Isto será restaurado automaticamente assim que o yuzu for fechado.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1571,37 +1608,47 @@ This would ban both their forum username and their IP address.</source>
<translation>Usar tempo de resposta rápido da GPU (Hack)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Filtro Anisotrópico:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>Automático</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Padrão</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2093,7 +2140,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Analógico Esquerdo</translation>
</message>
@@ -2187,14 +2234,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2213,7 +2260,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Mais</translation>
</message>
@@ -2226,15 +2273,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2291,231 +2338,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Analógico Direito</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Limpar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[não definido]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Alternar pressionamento do botão</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>Inverter botão</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Alternar pressionamento do botão</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Inverter eixo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>Definir limite</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Escolha um valor entre 0% e 100%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation>Definir limite do giroscópio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Mapear analógicos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Após pressionar OK, mova o seu analógico primeiro horizontalmente e depois verticalmente.
Para inverter os eixos, mova o seu analógico primeiro verticalmente e depois horizontalmente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation>Eixo central</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Ponto Morto: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Modificador de Alcance: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Comando Pro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Joycons Duplos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Joycon Esquerdo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Joycon Direito</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Portátil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>Controlador de depuração</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>Controle NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>Controle SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>Controle N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Mega Drive</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Iniciar / Pausar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Direcional de controle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Abane!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[em espera]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Novo Perfil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Introduza um novo nome de perfil:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Criar perfil de controlo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>O nome de perfil dado não é válido!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Falha ao criar o perfil de controlo &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Apagar Perfil de Controlo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Falha ao apagar o perfil de controlo &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Carregar perfil de controlo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Falha ao carregar o perfil de controlo &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Guardar perfil de controlo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Falha ao guardar o perfil de controlo &quot;%1&quot;</translation>
</message>
@@ -2770,42 +2822,42 @@ Para inverter os eixos, mova o seu analógico primeiro verticalmente e depois ho
<translation>Desenvolvedor</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Add-Ons</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Geral</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Gráficos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Gráficos Avç.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Audio</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Propriedades</translation>
</message>
@@ -3517,47 +3569,47 @@ Para inverter os eixos, mova o seu analógico primeiro verticalmente e depois ho
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Lê entradas de controle a partir de scripts no mesmo formato que TAS-nx. &lt;br/&gt;Para uma explicação mais detalhada, por favor consulte a &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;página de ajuda&lt;/span&gt;&lt;/a&gt; no website do yuzu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>Para checar que atalhos controlam rodar/gravar, por favor refira-se às Teclas de atalhos (Configurar -&gt; Geral -&gt; Teclas de atalhos)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>ATENÇÃO: Este é um recurso experimental. &lt;br/&gt;Não irá rodar os scrips em quadros perfeitos com o atual, imperfeito método de sincronização. </translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Configurações</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>Ativar funcionalidades TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>Repetir script em loop</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>Pausar execução durante carregamentos</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>Diretório do script</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Caminho</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3967,7 +4019,7 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Verificar</translation>
</message>
@@ -4054,7 +4106,7 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Não especificado</translation>
</message>
@@ -4069,17 +4121,36 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta
<translation>O token não foi verificado. A alteração do token não foi gravada.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>A verificar...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Verificação Falhada</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Verificação Falhada</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Verificação Falhada. Verifique se introduziu seu nome de utilizador e o token correctamente e se a conexão com a Internet está operacional.</translation>
</message>
@@ -4148,12 +4219,12 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation type="unfinished"/>
</message>
@@ -4161,910 +4232,890 @@ Arrasta os pontos para mudar a posição, ou dá duplo-clique nas células da ta
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Dados anônimos são coletados&lt;/a&gt;para ajudar a melhorar o yuzu.&lt;br/&gt;&lt;br/&gt;Gostaria de compartilhar seus dados de uso conosco?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetria</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>A Carregar o Web Applet ...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Desativar Web Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>A desativação do applet da web pode causar comportamento inesperado e deve apenas ser usada com Super Mario 3D All-Stars. Você deseja mesmo desativar o applet da web?
(Ele pode ser reativado nas configurações de depuração.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>Quantidade de shaders a serem construídos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>O atualmente multiplicador de escala de resolução selecionado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Velocidade da emulação actual. Valores acima ou abaixo de 100% indicam que a emulação está sendo executada mais depressa ou mais devagar do que a Switch</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Quantos quadros por segundo o jogo está exibindo de momento. Isto irá variar de jogo para jogo e de cena para cena.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tempo gasto para emular um frame da Switch, sem contar o a limitação de quadros ou o v-sync. Para emulação de velocidade máxima, esta deve ser no máximo 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Limpar arquivos recentes</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>&amp;Continuar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Pausa</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>yuzu está rodando um jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Aviso de Formato de Jogo Desactualizado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Você está usando o formato de directório ROM desconstruído para este jogo, que é um formato desactualizado que foi substituído por outros, como NCA, NAX, XCI ou NSP. Os directórios de ROM não construídos não possuem ícones, metadados e suporte de actualização.&lt;br&gt;&lt;br&gt;Para uma explicação dos vários formatos de Switch que o yuzu suporta,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;Verifique a nossa Wiki&lt;/a&gt;. Esta mensagem não será mostrada novamente.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Erro ao carregar o ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>O formato do ROM não é suportado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Ocorreu um erro ao inicializar o núcleo do vídeo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu encontrou um erro enquanto rodando o núcleo de vídeo. Normalmente isto é causado por drivers de GPU desatualizados, incluindo integrados. Por favor veja o registro para mais detalhes. Para mais informações em acesso ao registro por favor veja a seguinte página: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Como fazer envio de arquivo de registro&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Erro ao carregar a ROM! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Por favor, siga &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;a guia de início rápido do yuzu&lt;/a&gt; para fazer o redespejo dos seus arquivos.&lt;br&gt;Você pode consultar a wiki do yuzu&lt;/a&gt; ou o Discord do yuzu&lt;/a&gt; para obter ajuda.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Ocorreu um erro desconhecido. Por favor, veja o log para mais detalhes.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Save Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Mod Data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Erro ao abrir a pasta %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>A Pasta não existe!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Erro ao abrir os Shader Cache transferíveis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Falha ao criar o diretório de cache de shaders para este título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Conteúdos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Actualização</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Remover Entrada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>Remover Jogo Instalado %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>Removido com Sucesso</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>Removida a instalação do jogo base com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>Erro ao Remover %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>O jogo base não está instalado no NAND e não pode ser removido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>Removida a actualização instalada com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>Não há actualização instalada neste título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>Não há DLC instalado neste título.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Removido DLC instalado %1 com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Apagar o cache de shaders transferível do OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Apagar o cache de shaders transferível do Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Apagar todos os caches de shaders transferíveis?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>Remover Configuração Personalizada do Jogo?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Remover Ficheiro</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Error ao Remover Cache de Shader Transferível</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>O Shader Cache para este titulo não existe.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Removido a Cache de Shader Transferível com Sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Falha ao remover a cache de shader transferível.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Erro ao remover os caches de shaders transferíveis</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Os caches de shaders transferíveis foram removidos com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Falha ao remover o diretório do cache de shaders transferível.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Erro ao Remover Configuração Personalizada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Não existe uma configuração personalizada para este titúlo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Removida a configuração personalizada do jogo com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Falha ao remover a configuração personalizada do jogo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>A Extração de RomFS falhou!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Houve um erro ao copiar os arquivos RomFS ou o usuário cancelou a operação.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Cheio</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Esqueleto</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Selecione o modo de despejo do RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Por favor, selecione a forma como você gostaria que o RomFS fosse despejado&lt;br&gt;Full irá copiar todos os arquivos para o novo diretório enquanto&lt;br&gt;skeleton criará apenas a estrutura de diretórios.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>Não há espaço suficiente em %1 para extrair o RomFS. Por favor abra espaço ou selecione um diretório diferente em Emulação &gt; Configurar &gt; Sistema &gt; Sistema de arquivos &gt; Extrair raiz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Extraindo o RomFS ...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Cancelar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Extração de RomFS Bem-Sucedida!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>A operação foi completa com sucesso.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Erro ao abrir %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Selecione o Diretório</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Propriedades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>As propriedades do jogo não puderam ser carregadas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Executáveis Switch (%1);;Todos os Ficheiros (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Carregar Ficheiro</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Abrir o directório ROM extraído</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Diretório inválido selecionado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>O diretório que você selecionou não contém um arquivo &apos;Main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Ficheiro Switch Instalável (*.nca *.nsp *.xci);;Arquivo de Conteúdo Nintendo (*.nca);;Pacote de Envio Nintendo (*.nsp);;Imagem de Cartucho NX (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Instalar Ficheiros</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Instalando arquivo &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Instalar Resultados</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Para evitar possíveis conflitos, desencorajamos que os utilizadores instalem os jogos base na NAND.
Por favor, use esse recurso apenas para instalar atualizações e DLC.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Aplicação do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Arquivo do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Atualização do aplicativo do sistema</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Pacote de Firmware (Tipo A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Pacote de Firmware (Tipo B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Actualização do Jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>DLC do Jogo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Título Delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Selecione o tipo de instalação do NCA ...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Por favor, selecione o tipo de título que você gostaria de instalar este NCA como:
(Na maioria dos casos, o padrão &apos;Jogo&apos; é suficiente).</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Falha na instalação</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>O tipo de título que você selecionou para o NCA é inválido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Arquivo não encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Arquivo &quot;%1&quot; não encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Conta Yuzu Ausente</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Para enviar um caso de teste de compatibilidade de jogos, você deve vincular sua conta yuzu.&lt;br&gt;&lt;br/&gt;Para vincular sua conta yuzu, vá para Emulação &amp;gt; Configuração &amp;gt; Rede.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Erro ao abrir URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Não foi possível abrir o URL &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>Gravando TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>Sobrescrever arquivo do jogador 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>Configação inválida detectada</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>O comando portátil não pode ser usado no modo encaixado na base. O Pro controller será selecionado.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>Erro</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation>O jogo atual não está procurando amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation>O amiibo atual foi removido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Arquivo Amiibo (%1);; Todos os Arquivos (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Carregar Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Erro ao abrir o arquivo de dados do Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Não é possível abrir o arquivo Amiibo &quot;%1&quot; para leitura.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Erro ao ler o arquivo de dados do Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Não é possível ler completamente os dados do Amiibo. Espera-se que leia %1 bytes, mas só conseguiu ler %2 bytes.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Erro ao carregar dados do Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Não foi possível carregar os dados do Amiibo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Captura de Tela</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>Imagem PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>Situação TAS: Rodando %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>Situação TAS: Gravando %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>Situação TAS: Repouso %1%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>Situação TAS: Inválido</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>&amp;Parar de rodar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Começar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>Parar G&amp;ravação</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>G&amp;ravação</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Escala: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Velocidade: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Velocidade: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Jogo: %1 FPS (Desbloqueado)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Jogo: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Quadro: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU ALTA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU EXTREMA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>ERRO DE GPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>VIZINHO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>BILINEAR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>BICÚBICO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>GAUSSIANO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>Sem AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>O jogo que você está tentando carregar requer arquivos adicionais do seu Switch para serem despejados antes de jogar.&lt;br/&gt;&lt;br/&gt;Para obter mais informações sobre como despejar esses arquivos, consulte a seguinte página da wiki:&lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Despejando arquivos do sistema e as fontes compartilhadas de uma consola Switch&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Você gostaria de regressar para a lista de jogos? Continuar a emulação pode resultar em falhas, dados de salvamento corrompidos ou outros erros.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>O yuzu não conseguiu localizar um arquivo de sistema do Switch. % 1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>O yuzu não conseguiu localizar um arquivo de sistema do Switch: %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Arquivo do Sistema Não Encontrado</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Arquivo de Sistema em falta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu não conseguiu localizar as fontes compartilhadas do Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Fontes compartilhadas não encontradas</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Fontes compartilhadas em falta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Erro fatal</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu encontrou um erro fatal, por favor veja o registro para mais detalhes. Para mais informações sobre como acessar o registro, por favor, veja a seguinte página:&lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Como carregar o arquivo de registro&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Você gostaria de regressar para a lista de jogos? Continuar a emulação pode resultar em falhas, dados de salvamento corrompidos ou outros erros.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Ocorreu um Erro fatal</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Confirme a rederivação da chave</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5081,37 +5132,37 @@ e opcionalmente faça backups.
Isso irá excluir os seus arquivos de chave gerados automaticamente e executará novamente o módulo de derivação de chave.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>Fusíveis em Falta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation>- BOOT0 em Falta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- BCPKG2-1-Normal-Main em Falta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation>- PRODINFO em Falta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>Componentes de Derivação em Falta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Chaves de encriptação faltando. &lt;br&gt;Por favor, siga &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;o guia de início rápido&lt;/a&gt; para extrair suas chaves, firmware e jogos. &lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5120,39 +5171,39 @@ Isto pode demorar até um minuto, dependendo
do desempenho do seu sistema.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Derivando Chaves</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Selecione o destino de despejo do RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Por favor, selecione qual o RomFS que você gostaria de despejar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Tem a certeza que quer fechar o yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Tem a certeza de que quer parar a emulação? Qualquer progresso não salvo será perdido.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5508,7 +5559,7 @@ Inicial</translation>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="139"/>
<source>Room Description</source>
- <translation type="unfinished"/>
+ <translation>Descrição da sala</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="153"/>
@@ -5534,12 +5585,12 @@ Inicial</translation>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>Erro</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5548,11 +5599,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5574,112 +5626,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Captura de Tela</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Tela Cheia</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Carregar Ficheiro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5794,42 +5845,42 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Jogadores</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation type="unfinished"/>
</message>
@@ -5999,7 +6050,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/main.ui" line="270"/>
<source>Leave Room</source>
- <translation type="unfinished"/>
+ <translation>Sair da sala</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="275"/>
@@ -6156,7 +6207,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Conectado</translation>
</message>
@@ -6178,7 +6229,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation type="unfinished"/>
</message>
@@ -6282,22 +6333,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
- <source>Leave Room</source>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
+ <source>Leave Room</source>
+ <translation>Sair da sala</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6305,7 +6373,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>Erro</translation>
</message>
@@ -6364,7 +6432,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation type="unfinished"/>
</message>
@@ -6419,7 +6487,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[não configurado]</translation>
</message>
@@ -6434,10 +6502,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Eixo %1%2</translation>
</message>
@@ -6451,9 +6519,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[Desconhecido]</translation>
</message>
@@ -6618,15 +6686,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[inválido]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation>%1%2Direcional %3</translation>
</message>
@@ -6634,35 +6702,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation>%1%2Eixo %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation>%1%2Eixo %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2Movimentação %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2Botão %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[sem uso]</translation>
</message>
@@ -6703,7 +6771,7 @@ p, li { white-space: pre-wrap; }
<translation>Extra</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/languages/ru_RU.ts b/dist/languages/ru_RU.ts
index 8ba92a5b7..5bbf4e6b0 100644
--- a/dist/languages/ru_RU.ts
+++ b/dist/languages/ru_RU.ts
@@ -95,78 +95,78 @@ p, li { white-space: pre-wrap; }
<translation>Отправить сообщение</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation>Участники</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation>%1 присоединился</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation>%1 вышел</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation>%1 был выгнан</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation>%1 был забанен</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation>%1 был разбанен</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation>Посмотреть профиль</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation>Заблокировать игрока</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation>Когда вы блокируете игрока, вы больше не будете получать от него сообщения в чате.&lt;br&gt;&lt;br&gt;Вы уверены, что хотите заблокировать %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation>Выгнать</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation>Забанить</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation>Выгнать игрока</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation>Вы уверены, что хотите &lt;b&gt;выгнать&lt;/b&gt; %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation>Забанить игрока</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -771,200 +771,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation>Отладчик</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Включить GDB Stub</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Порт:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Журналирование</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Глобальный фильтр журналов</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Показывать журнал в консоли</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Открыть папку для журналов</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Если включено, максимальный размер журнала увеличивается со 100 МБ до 1 ГБ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Включить расширенное ведение журнала**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Строка аргументов</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Графика</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Если включено, графический API переходит в более медленный режим отладки</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Включить отладку графики</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>Если включено, включает дампы крашей Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Включить Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation>Если включено, будет дампить все оригинальные шейдеры ассемблера из кэша шейдеров на диске или игры как найденные</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation>Дамп игровых шейдеров</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation>Если включено, будет дампить все макропрограммы ГП</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation>Дамп макросов Maxwell</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>Если включено, отключает компилятор макроса Just In Time. Включение опции делает игры медленнее</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Отключить Макрос JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>Если включено, yuzu будет записывать статистику о скомпилированном кэше конвейера</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>Включить обратную связь о шейдерах</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>Если включено, производит выполнение шейдеров без изменения логики цикла</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>Отключить проверку безопасности цикла</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Отладка</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
- <source>Enable FS Access Log</source>
- <translation>Включить журнал доступа к FS</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>Включить службу отчётов в развернутом виде**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
- <translation>Дамп аудиокоманд в консоль**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
+ <translation>Включить журнал доступа к FS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>Включите эту опцию, чтобы выводить на консоль последний сгенерированный список аудиокоманд. Влияет только на игры, использующие аудио рендерер.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>Включить службу отчётов в развернутом виде**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
+ <translation>Дамп аудиокоманд в консоль**</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Дополнительно</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Режим киоска (Квест)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Включить отладку ЦП</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Включить отладочные сигналы</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>Включить Автоподставку**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation>Включить все типы контроллеров</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Отключить веб-апплет</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Это будет автоматически сброшено после закрытия yuzu.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1560,7 +1595,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="78"/>
<source>Use VSync</source>
- <translation type="unfinished"/>
+ <translation>Использовать вертикальную синхронизацию</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="85"/>
@@ -1583,37 +1618,47 @@ This would ban both their forum username and their IP address.</source>
<translation>Включить Fast GPU Time (Хак)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation>Включает пессимистическую очистку буферов. Эта опция заставляет промывать немодифицированные буферы, что может снизить производительность.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation>Использовать пессимистическую очистку буферов (Хак)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Анизотропная Фильтрация:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>Автоматически</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Стандартная</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2105,7 +2150,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Левый стик</translation>
</message>
@@ -2199,14 +2244,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2225,7 +2270,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Плюс</translation>
</message>
@@ -2238,15 +2283,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2303,231 +2348,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Правый стик</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Очистить</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[не задано]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Переключить кнопку</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>Инвертировать кнопку</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Переключить кнопку</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Инвертировать оси</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>Установить порог</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Выберите значение между 0% и 100%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation>Переключить оси</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation>Установить порог гироскопа</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Задать аналоговый стик</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>После нажатия на ОК, двигайте ваш джойстик горизонтально, а затем вертикально.
Чтобы инвертировать оси, сначала двигайте ваш джойстик вертикально, а затем горизонтально.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation>Центрировать оси</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Мёртвая зона: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Диапазон модификатора: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Контроллер Pro</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Двойные Joycon&apos;ы</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Левый Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Правый Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Портативный</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>Контроллер GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>Контроллер NES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>Контроллер SNES</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>Контроллер N64</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Старт / Пауза</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Стик управления</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Стик</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Встряхните!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[ожидание]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Новый профиль</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Введите имя профиля:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Создать профиль управления</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>Заданное имя профиля недействительно!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Не удалось создать профиль управления &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Удалить профиль управления</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Не удалось удалить профиль управления &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Загрузить профиль управления</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Не удалось загрузить профиль управления &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Сохранить профиль управления</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Не удалось сохранить профиль управления &quot;%1&quot;</translation>
</message>
@@ -2782,42 +2832,42 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation>Разработчик</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Дополнения</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Общие</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Система</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>ЦП</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Графика</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Расш. Графика</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Звук</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Свойства</translation>
</message>
@@ -3529,47 +3579,47 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Считывает входные данные контроллера из скриптов в том же формате, что и скрипты TAS-nx.&lt;br/&gt;Для более подробного объяснения обратитесь к &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;странице помощи&lt;/span&gt;&lt;/a&gt; на сайте yuzu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>Чтобы проверить, какие горячие клавиши управляют воспроизведением/записью, обратитесь к настройкам горячих клавиш (Настройки - Общие -&gt; Горячие клавиши).</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>ПРЕДУПРЕЖДЕНИЕ: Это экспериментальная функция.&lt;br/&gt;Она не будет идеально воспроизводить кадры сценариев при текущем несовершенном методе синхронизации.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Настройки</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>Включить функции TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>Зациклить скрипт</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>Приостановить выполнение во время загрузки</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>Папка для скриптов</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Путь</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3979,7 +4029,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Подтвердить</translation>
</message>
@@ -4066,7 +4116,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Отсутствует</translation>
</message>
@@ -4081,17 +4131,36 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Токен не был подтвержден. Изменение вашего токена не было сохранено.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Проверка...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Ошибка подтверждения</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Ошибка подтверждения</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Ошибка подтверждения. Убедитесь, что вы правильно ввели свой токен и что ваше подключение к Интернету работает.</translation>
</message>
@@ -4160,12 +4229,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation>Подключение</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation>Подключиться</translation>
</message>
@@ -4173,488 +4242,488 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Анонимные данные собираются для того,&lt;/a&gt; чтобы помочь улучшить работу yuzu. &lt;br/&gt;&lt;br/&gt;Хотели бы вы делиться данными об использовании с нами?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Телеметрия</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation>Обнаружена поврежденная установка Vulkan</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Не удалось выполнить инициализацию Vulkan во время загрузки.&lt;br&gt;&lt;br&gt;Нажмите &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;здесь для получения инструкций по устранению проблемы&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Загрузка веб-апплета...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Отключить веб-апплет</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>Отключение веб-апплета может привести к неожиданному поведению и должно использоваться только с Super Mario 3D All-Stars. Вы уверены, что хотите отключить веб-апплет?
(Его можно снова включить в настройках отладки.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>Количество создаваемых шейдеров на данный момент</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Текущий выбранный множитель масштабирования разрешения.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Текущая скорость эмуляции. Значения выше или ниже 100% указывают на то, что эмуляция идет быстрее или медленнее, чем на Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Количество кадров в секунду в данный момент. Значение будет меняться между играми и сценами.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Время, которое нужно для эмуляции 1 кадра Switch, не принимая во внимание ограничение FPS или вертикальную синхронизацию. Для эмуляции в полной скорости значение должно быть не больше 16,67 мс.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>[&amp;C] Очистить недавние файлы</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>[&amp;C] Продолжить</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>[&amp;P] Пауза</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>В yuzu запущена игра</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Предупреждение устаревший формат игры</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Для этой игры вы используете разархивированный формат ROM&apos;а, который является устаревшим и был заменен другими, такими как NCA, NAX, XCI или NSP. В разархивированных каталогах ROM&apos;а отсутствуют иконки, метаданные и поддержка обновлений. &lt;br&gt;&lt;br&gt;Для получения информации о различных форматах Switch, поддерживаемых yuzu, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;просмотрите нашу вики&lt;/a&gt;. Это сообщение больше не будет отображаться.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Ошибка при загрузке ROM&apos;а!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>Формат ROM&apos;а не поддерживается.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Произошла ошибка при инициализации видеоядра.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu столкнулся с ошибкой при запуске видеоядра. Обычно это вызвано устаревшими драйверами GPU, включая интегрированные. Проверьте журнал для получения более подробной информации. Дополнительную информацию о доступе к журналу смотрите на следующей странице: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Как загрузить файл журнала&lt;/a&gt;. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>Ошибка при загрузке ROM&apos;а! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Пожалуйста, следуйте &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;краткому руководству пользователя yuzu&lt;/a&gt; чтобы пере-дампить ваши файлы&lt;br&gt;Вы можете обратиться к вики yuzu&lt;/a&gt; или Discord yuzu&lt;/a&gt; для помощи.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Произошла неизвестная ошибка. Пожалуйста, проверьте журнал для подробностей.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-х битный)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-х битный)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Сохранения</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Данные модов</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Ошибка при открытии папки %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Папка не существует!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Ошибка при открытии переносного кэша шейдеров</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Не удалось создать папку кэша шейдеров для этой игры.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Содержание</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Обновление</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>Загружаемый контент</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Удалить запись</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>Удалить установленную игру %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>Успешно удалено</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>Установленная игра успешно удалена.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>Ошибка при удалении %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Игра не установлена в NAND и не может быть удалена.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>Установленное обновление успешно удалено.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>Для этой игры не было установлено обновление.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>Для этой игры не был установлен загружаемый контент.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Установленный загружаемый контент %1 был успешно удалён</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>Удалить переносной кэш шейдеров OpenGL?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Удалить переносной кэш шейдеров Vulkan?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Удалить весь переносной кэш шейдеров?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>Удалить пользовательскую настройку игры?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Удалить файл</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Ошибка при удалении переносного кэша шейдеров</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>Кэш шейдеров для этой игры не существует.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Переносной кэш шейдеров успешно удалён.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Не удалось удалить переносной кэш шейдеров.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Ошибка при удалении переносного кэша шейдеров</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Переносной кэш шейдеров успешно удален.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Ошибка при удалении папки переносного кэша шейдеров.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Ошибка при удалении пользовательской настройки</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Пользовательская настройка для этой игры не существует.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Пользовательская настройка игры успешно удалена.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Не удалось удалить пользовательскую настройку игры.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>Не удалось извлечь RomFS!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Произошла ошибка при копировании файлов RomFS или пользователь отменил операцию.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Полный</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Скелет</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Выберите режим дампа RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Пожалуйста, выберите, как вы хотите выполнить дамп RomFS. &lt;br&gt;Полный скопирует все файлы в новую папку, в то время как &lt;br&gt;скелет создаст только структуру папок.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>В %1 недостаточно свободного места для извлечения RomFS. Пожалуйста, освободите место или выберите другую папку для дампа в Эмуляция &gt; Настройка &gt; Система &gt; Файловая система &gt; Корень дампа</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Извлечение RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Отмена</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Извлечение RomFS прошло успешно!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>Операция выполнена.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Ошибка открытия %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Выбрать папку</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Свойства</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Не удалось загрузить свойства игры.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Исполняемый файл Switch (%1);;Все файлы (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Загрузить файл</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Открыть папку извлечённого ROM&apos;а</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Выбрана недопустимая папка</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Папка, которую вы выбрали, не содержит файла &apos;main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Устанавливаемый файл Switch (*.nca, *.nsp, *.xci);;Архив контента Nintendo (*.nca);;Пакет подачи Nintendo (*.nsp);;Образ картриджа NX (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Установить файлы</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>Остался %n файл</numerusform><numerusform>Осталось %n файл(ов)</numerusform><numerusform>Осталось %n файл(ов)</numerusform><numerusform>Осталось %n файл(ов)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Установка файла &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Установить результаты</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Чтобы избежать возможных конфликтов, мы не рекомендуем пользователям устанавливать игры в NAND.
Пожалуйста, используйте эту функцию только для установки обновлений и загружаемого контента.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n файл был недавно установлен
@@ -4664,7 +4733,7 @@ Please, only use this feature to install updates and DLC.</source>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n файл был перезаписан
@@ -4674,7 +4743,7 @@ Please, only use this feature to install updates and DLC.</source>
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n файл не удалось установить
@@ -4684,411 +4753,391 @@ Please, only use this feature to install updates and DLC.</source>
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Системное приложение</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Системный архив</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Обновление системного приложения</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Пакет прошивки (Тип А)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Пакет прошивки (Тип Б)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Игра</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Обновление игры</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>Загружаемый контент игры</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Дельта-титул</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Выберите тип установки NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Пожалуйста, выберите тип приложения, который вы хотите установить для этого NCA:
(В большинстве случаев, подходит стандартный выбор «Игра».)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Ошибка установки</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Тип приложения, который вы выбрали для NCA, недействителен.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Файл не найден</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Файл &quot;%1&quot; не найден</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>ОК</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Отсутствует аккаунт yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Чтобы отправить отчет о совместимости игры, необходимо привязать свою учетную запись yuzu.&lt;br&gt;&lt;br/&gt;Чтобы привязать свою учетную запись yuzu, перейдите в раздел Эмуляция &amp;gt; Параметры &amp;gt; Сеть.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Ошибка при открытии URL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Не удалось открыть URL: &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>Запись TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>Перезаписать файл игрока 1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>Обнаружена недопустимая конфигурация</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Портативный контроллер не может быть использован в режиме док-станции. Будет выбран контроллер Pro.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>Ошибка</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation>Текущая игра не ищет amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation>Текущий amiibo был убран</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Файл Amiibo (%1);; Все Файлы (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Загрузить Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Ошибка открытия файла данных Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Невозможно открыть файл Amiibo &quot;%1&quot; для чтения.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Ошибка чтения файла данных Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Невозможно полностью прочитать данные Amiibo. Ожидалось прочитать %1 байт, но удалось прочитать только %2 байт.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Ошибка загрузки данных Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Невозможно загрузить данные Amiibo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Сделать скриншот</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>Изображение PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>Состояние TAS: Выполняется %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>Состояние TAS: Записывается %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>Состояние TAS: Простой %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>Состояние TAS: Неверное</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>[&amp;S] Остановка</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>[&amp;S] Начать</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>[&amp;E] Закончить запись</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>[&amp;E] Запись</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Постройка: %n шейдер</numerusform><numerusform>Постройка: %n шейдер(ов)</numerusform><numerusform>Постройка: %n шейдер(ов)</numerusform><numerusform>Постройка: %n шейдер(ов)</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Масштаб: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Скорость: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Скорость: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Игра: %1 FPS (Неограниченно)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Игра: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Кадр: %1 мс</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>ГП НОРМАЛЬНО</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>ГП ВЫСОКО</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>ГП ЭКСТРИМ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>ГП ОШИБКА</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation>В ДОК-СТАНЦИИ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation>ПОРТАТИВНЫЙ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>БЛИЖАЙШИЙ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>БИЛИНЕЙНЫЙ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>БИКУБИЧЕСКИЙ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>ГАУСС</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>БЕЗ СГЛАЖИВАНИЯ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>Игра, которую вы пытаетесь загрузить, требует, чтобы дополнительные файлы были сдамплены с вашего Switch перед началом игры. &lt;br/&gt;&lt;br/&gt;Для получения дополнительной информации о дампе этих файлов см. следующую вики: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Дамп системных архивов и общих шрифтов с консоли&lt;/a&gt;. &lt;br/&gt;&lt;br/&gt;Хотите вернуться к списку игр? Продолжение эмуляции может привести к сбоям, повреждению сохраненных данных или другим ошибкам.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>yuzu не удалось найти системный архив Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>yuzu не удалось найти системный архив Switch: %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Системный архив не найден</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Отсутствует системный архив</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu не удалось найти общие шрифты Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Общие шрифты не найдены</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Общие шрифты отсутствуют</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Фатальная ошибка</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu столкнулся с фатальной ошибкой, проверьте журнал для получения более подробной информации. Для получения дополнительной информации о доступе к журналу откройте следующую страницу: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Как загрузить файл журнала&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Вы хотите вернуться к списку игр? Продолжение эмуляции может привести к сбоям, повреждению сохранений или другим ошибкам.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Произошла фатальная ошибка</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Подтвердите перерасчет ключа</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5105,37 +5154,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
Это удалит ваши автоматически сгенерированные файлы ключей и повторно запустит модуль расчета ключей.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>Отсутствуют предохранители</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation>- Отсутствует BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- Отсутствует BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation>- Отсутствует PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>Компоненты расчета отсутствуют</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Ключи шифрования отсутствуют. &lt;br&gt;Пожалуйста, следуйте &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;краткому руководству пользователя yuzu&lt;/a&gt;, чтобы получить все ваши ключи, прошивку и игры.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5144,39 +5193,39 @@ on your system&apos;s performance.</source>
от производительности вашей системы.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Получение ключей</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Выберите цель для дампа RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Пожалуйста, выберите, какой RomFS вы хотите сдампить.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Вы уверены, что хотите закрыть yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Вы уверены, что хотите остановить эмуляцию? Любой несохраненный прогресс будет потерян.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5558,12 +5607,12 @@ Screen.</source>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>Ошибка</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation>Не удалось объявить комнату в публичном лобби. Чтобы хостить публичную комнату, у вас должна быть действующая учетная запись yuzu, настроенная в Эмуляция -&gt; Параметры -&gt; Сеть. Если вы не хотите объявлять комнату в публичном лобби, выберите вместо этого скрытый тип.
@@ -5573,11 +5622,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation>Включение/отключение звука</translation>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5599,112 +5649,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation>Основное окно</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation>Уменьшить громкость звука</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation>Повысить громкость звука</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Сделать скриншот</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation>Изменить адаптирующий фильтр</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation>Изменить режим консоли</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation>Изменить точность ГП</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation>Продолжение/Пауза эмуляции</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation>Выйти из полноэкранного режима</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation>Выйти из yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Полный экран</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Загрузить файл</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation>Загрузить/удалить Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation>Перезапустить эмуляцию</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation>Остановить эмуляцию</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation>Запись TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation>Сброс TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation>Старт/Стоп TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation>Переключить панель поиска</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation>Переключить ограничение частоты кадров</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation>Переключить панорамирование мыши</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation>Переключить панель состояния</translation>
</message>
@@ -5819,42 +5868,42 @@ Debug Message: </source>
<translation>Обновить лобби</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation>Для входа необходим пароль</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation>Пароль:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation>Название комнаты</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation>Предпочтительная игра</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation>Хост</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Игроки</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation>Обновление</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation>Обновить список</translation>
</message>
@@ -6181,7 +6230,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Подключено</translation>
</message>
@@ -6204,7 +6253,7 @@ Debug Message: </source>
Сообщение отладки:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation>Получены новые сообщения</translation>
</message>
@@ -6294,7 +6343,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="47"/>
<source>IP address is already in use. Please choose another.</source>
- <translation type="unfinished"/>
+ <translation>IP-адрес уже используется. Пожалуйста, выберите другой.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="49"/>
@@ -6309,22 +6358,41 @@ They may have left the room.</source>
Возможно, они покинули комнату.</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation>Не выбран интерфейс сети.
+Пожалуйста, перейдите в Параметры -&gt; Система -&gt; Сеть и сделайте выбор.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation>Игра уже запущена</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation>Присоединяться к комнате, когда игра уже запущена, не рекомендуется, это может привести к неправильной работе функции комнаты.
+Все равно продолжить?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation>Покинуть комнату</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation>Вы собираетесь закрыть комнату. Все сетевые подключения будут закрыты.</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation>Отключиться</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation>Вы собираетесь покинуть комнату. Все сетевые подключения будут закрыты.</translation>
</message>
@@ -6332,7 +6400,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>Ошибка</translation>
</message>
@@ -6391,7 +6459,7 @@ p, li { white-space: pre-wrap; }
<translation>%1 играет в %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation>Не играет в игру</translation>
</message>
@@ -6446,7 +6514,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[не задано]</translation>
</message>
@@ -6461,10 +6529,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Ось %1%2</translation>
</message>
@@ -6478,9 +6546,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[неизвестно]</translation>
</message>
@@ -6645,15 +6713,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[недопустимо]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation>%1%2Крест. %3</translation>
</message>
@@ -6661,35 +6729,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation>%1%2Ось %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation>%1%2Ось %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2Движение %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2Кнопка %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[не используется]</translation>
</message>
@@ -6730,7 +6798,7 @@ p, li { white-space: pre-wrap; }
<translation>Дополнительная</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/languages/sv.ts b/dist/languages/sv.ts
index 00d08a5ef..eda556290 100644
--- a/dist/languages/sv.ts
+++ b/dist/languages/sv.ts
@@ -89,78 +89,78 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -740,200 +740,235 @@ avgjord kod.&lt;/div&gt;
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Aktivera GDB Stub</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Port:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Loggning</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Globalt Loggfilter</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Öppna Logg-Destination</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Argumentsträng</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Grafik</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Sätt på grafikdebugging</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Stäng av Macro JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Felsökning</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
- <source>Enable FS Access Log</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Avancerat</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Kiosk(Quest)-läge</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation type="unfinished"/>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1552,37 +1587,47 @@ avgjord kod.&lt;/div&gt;
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Anisotropisk filtrering:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Standard</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2074,7 +2119,7 @@ avgjord kod.&lt;/div&gt;
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Vänster Spak</translation>
</message>
@@ -2168,14 +2213,14 @@ avgjord kod.&lt;/div&gt;
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2194,7 +2239,7 @@ avgjord kod.&lt;/div&gt;
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Pluss</translation>
</message>
@@ -2207,15 +2252,15 @@ avgjord kod.&lt;/div&gt;
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2272,230 +2317,235 @@ avgjord kod.&lt;/div&gt;
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Höger Spak</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Rensa</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[ej angett]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
+ <source>Invert button</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
- <source>Invert button</source>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Dödzon: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Modifieringsräckvidd: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Prokontroller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Dubbla Joycons</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Vänster Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Höger Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Handhållen</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[väntar]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Ny profil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation type="unfinished"/>
</message>
@@ -2750,42 +2800,42 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation>Utvecklare</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Tillägg</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Allmänt</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>System</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Grafik</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Avancerade Grafikinställningar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Ljud</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>egenskaper</translation>
</message>
@@ -3497,47 +3547,47 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Sökväg</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3947,7 +3997,7 @@ Dra punkter för att ändra position, eller dubbelklicka tabellceller för att r
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Verifiera</translation>
</message>
@@ -4034,7 +4084,7 @@ Dra punkter för att ändra position, eller dubbelklicka tabellceller för att r
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Ospecificerat</translation>
</message>
@@ -4049,17 +4099,36 @@ Dra punkter för att ändra position, eller dubbelklicka tabellceller för att r
<translation>Polletten verifierades inte. Ändringen till din pollett har inte sparats.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Verifierar...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Verifiering misslyckad</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Verifiering misslyckad</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Verifiering misslyckad. Kontrollera att du har skrivit in din pollett korrekt, och att din internetuppkoppling fungerar.</translation>
</message>
@@ -4128,12 +4197,12 @@ Dra punkter för att ändra position, eller dubbelklicka tabellceller för att r
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation type="unfinished"/>
</message>
@@ -4141,908 +4210,888 @@ Dra punkter för att ändra position, eller dubbelklicka tabellceller för att r
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonym data skickas &lt;/a&gt;För att förbättra yuzu. &lt;br/&gt;&lt;br/&gt;Vill du dela med dig av din användarstatistik med oss?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Laddar WebApplet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>Mängden shaders som just nu byggs</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Nuvarande emuleringshastighet. Värden över eller under 100% indikerar på att emulationen körs snabbare eller långsammare än en Switch.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Hur många bilder per sekund som spelet just nu visar. Detta varierar från spel till spel och scen till scen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Tid det tar att emulera en Switch bild, utan att räkna med framelimiting eller v-sync. För emulering på full hastighet så ska det vara som mest 16.67 ms. </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Paus</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Varning Föråldrat Spelformat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Du använder det dekonstruerade ROM-formatet för det här spelet. Det är ett föråldrat format som har överträffats av andra som NCA, NAX, XCI eller NSP. Dekonstruerade ROM-kataloger saknar ikoner, metadata och uppdatering.&lt;br&gt;&lt;br&gt;För en förklaring av de olika format som yuzu stöder, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;kolla in vår wiki&lt;/a&gt;. Det här meddelandet visas inte igen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Fel vid laddning av ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>ROM-formatet stöds inte.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Ett fel inträffade vid initiering av videokärnan.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Ett okänt fel har uppstått. Se loggen för mer information.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Spardata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Mod-data</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Fel Öppnar %1 Mappen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Mappen finns inte!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Fel Under Öppning Av Överförbar Shadercache</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>Innehåll</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Uppdatera</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Ta bort katalog</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>Ta Bort Installerat Spel %1?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>Framgångsrikt borttagen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>Tog bort det installerade basspelet framgångsrikt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>Fel Under Borttagning Av %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Basspelet är inte installerat i NAND och kan inte tas bort.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>Tog bort den installerade uppdateringen framgångsrikt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>Det finns ingen uppdatering installerad för denna titel.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>Det finns inga DLC installerade för denna titel.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>Tog framgångsrikt bort den %1 installerade DLCn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>Ta Bort Anpassad Spelkonfiguration?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Radera fil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Fel När Överförbar Shader Cache Raderades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>En shader cache för denna titel existerar inte.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Raderade den överförbara shadercachen framgångsrikt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Misslyckades att ta bort den överförbara shadercache</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Fel När Anpassad Konfiguration Raderades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>En anpassad konfiguration för denna titel existerar inte.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Tog bort den anpassade spelkonfigurationen framgångsrikt.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Misslyckades att ta bort den anpassade spelkonfigurationen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS Extraktion Misslyckades!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Det uppstod ett fel vid kopiering av RomFS filer eller användaren avbröt operationen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Full</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Skelett</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Välj RomFS Dump-Läge</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Välj hur du vill att RomFS ska dumpas. &lt;br&gt;Full kommer att kopiera alla filer i den nya katalogen medan &lt;br&gt;skelett bara skapar katalogstrukturen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Extraherar RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Avbryt</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS Extraktion Lyckades!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>Operationen var lyckad.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>Fel under öppning av %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Välj Katalog</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Egenskaper</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Spelegenskaperna kunde inte laddas.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch Körbar (%1);;Alla Filer (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Ladda Fil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Öppna Extraherad ROM-Katalog</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Ogiltig Katalog Vald</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Katalogen du har valt innehåller inte en &apos;main&apos;-fil.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Installerbar Switch-fil (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Installera filer</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Installerar Fil &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Installera resultat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Systemapplikation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Systemarkiv</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Systemapplikationsuppdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Firmwarepaket (Typ A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Firmwarepaket (Typ B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Spel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Speluppdatering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>Spel DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Delta Titel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Välj NCA-Installationsläge...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Välj vilken typ av titel du vill installera som:
(I de flesta fallen, standard &apos;Spel&apos; är bra.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Misslyckades med Installationen</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Den titeltyp du valt för NCA är ogiltig.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Filen hittades inte</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Filen &quot;%1&quot; hittades inte</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>yuzu Konto hittades inte</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>För att skicka ett spelkompatibilitetstest, du måste länka ditt yuzu-konto.&lt;br&gt;&lt;br/&gt;För att länka ditt yuzu-konto, gå till Emulering &amp;gt, Konfigurering &amp;gt, Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>Fel när URL öppnades</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>Oförmögen att öppna URL:en &quot;%1&quot;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo Fil (%1);; Alla Filer (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Ladda Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Fel öppnar Amiibo-datafilen</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Kunde inte öppna Amiibo filen &quot;%1&quot; för läsning.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Fel vid läsning av Amiibo-datafil</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Kan inte läsa Amiibo-data helt. Förväntas läsa %1 byte, men kunde bara läsa %2 byte.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Fel vid laddning av Amiibodata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Kan inte ladda Amiibodata.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Skärmdump</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>PNG Bild (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Start</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Hastighet: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Hastighet: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Spel: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Ruta: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>Spelet du försöker ladda kräver att ytterligare filer dumpas från din Switch innan du spelar.&lt;br/&gt;&lt;br/&gt;För mer information om dumpning av dessa filer, se följande wiki sida: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumpning System Arkiv och Delade Teckensnitt från en Switchkonsol&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Vill du avsluta till spellistan? Fortsatt emulering kan leda till kraschar, skadad spara data och andra buggar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>yuzu kunde inte lokalisera ett Switchsystemarkiv. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>yuzu kunde inte lokalisera ett Switchsystemarkiv: %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Systemarkivet Hittades Inte</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Systemarkiv Saknas</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu kunde inte lokalisera Switchens delade fonter. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Delade Teckensnitt Hittades Inte</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Delad Font Saknas</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Dödligt Fel</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu stötte på ett dödligt fel, se loggen för mer information. För mer information om åtkomst till loggen, se följande sida: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Hur man Laddar upp Loggfilen&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Vill du avsluta till spellistan? Fortsatt emulering kan leda till kraschar, skadad spara data och andra buggar.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Allvarligt fel påträffat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Bekräfta Nyckel Rederivering</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5059,37 +5108,37 @@ och eventuellt göra säkerhetskopior.
Detta raderar dina autogenererade nyckelfiler och kör nyckelderivationsmodulen.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>Saknade säkringar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation>- Saknar BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- Saknar BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation>- Saknar PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>Deriveringsdelar saknas</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5098,39 +5147,39 @@ Detta kan ta upp till en minut beroende
på systemets prestanda.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Härleda Nycklar</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Välj RomFS Dumpa Mål</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Välj vilken RomFS du vill dumpa.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Är du säker på att du vill stänga yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Är du säker på att du vill stoppa emuleringen? Du kommer att förlora osparade framsteg.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5512,12 +5561,12 @@ startskärmen.</translation>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5526,11 +5575,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5552,112 +5602,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Skärmdump</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Fullskärm</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Ladda Fil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5771,42 +5820,42 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Spelare</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation type="unfinished"/>
</message>
@@ -6133,7 +6182,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Kopplad</translation>
</message>
@@ -6155,7 +6204,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation type="unfinished"/>
</message>
@@ -6259,22 +6308,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6282,7 +6348,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
@@ -6337,7 +6403,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation type="unfinished"/>
</message>
@@ -6392,7 +6458,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[inte inställd]</translation>
</message>
@@ -6407,10 +6473,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Axel %1%2</translation>
</message>
@@ -6424,9 +6490,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[okänd]</translation>
</message>
@@ -6591,15 +6657,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation type="unfinished"/>
</message>
@@ -6607,35 +6673,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[oanvänd]</translation>
</message>
@@ -6676,7 +6742,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation type="unfinished"/>
</message>
diff --git a/dist/languages/tr_TR.ts b/dist/languages/tr_TR.ts
index 1e5c846bf..89e1f2692 100644
--- a/dist/languages/tr_TR.ts
+++ b/dist/languages/tr_TR.ts
@@ -25,12 +25,18 @@ p, li { white-space: pre-wrap; }
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:12pt;&quot;&gt;yuzu is an experimental open-source emulator for the Nintendo Switch licensed under GPLv3.0+.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:12pt;&quot;&gt;This software should not be used to play games you have not legally obtained.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Ubuntu&apos;; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:12pt;&quot;&gt;Yuzu GPLv3.0+ ile lisanslanmış Nintendo Switch için açık kaynak bir deneysel emülatördür.&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:&apos;MS Shell Dlg 2&apos;; font-size:8pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:12pt;&quot;&gt;Bu yazılım yasal yollarla edinilmemiş oyunları çalıştırmak için kullanılmamalı.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="130"/>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"/>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt;|&lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Kaynak Kodu&lt;/span&gt;&lt;/a&gt;|&lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Katkıda Bulunanlar&lt;/span&gt;&lt;/a&gt;|&lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Lisans&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<location filename="../../src/yuzu/aboutdialog.ui" line="146"/>
@@ -76,91 +82,91 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="14"/>
<source>Room Window</source>
- <translation type="unfinished"/>
+ <translation>Oda Penceresi</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="40"/>
<source>Send Chat Message</source>
- <translation type="unfinished"/>
+ <translation>Sohbet Mesajı At</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/chat_room.ui" line="47"/>
<source>Send Message</source>
- <translation type="unfinished"/>
+ <translation>Mesaj Gönder</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
- <translation type="unfinished"/>
+ <translation>Üyeler</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
- <translation type="unfinished"/>
+ <translation>%1 katıldı</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
- <translation type="unfinished"/>
+ <translation>%1 ayrıldı</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
- <translation type="unfinished"/>
+ <translation>%1 atıldı</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
- <translation type="unfinished"/>
+ <translation>%1 yasaklandı</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
- <translation type="unfinished"/>
+ <translation>%1&apos;in yasağı kaldırıldı</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
- <translation type="unfinished"/>
+ <translation>Profili Görüntüle</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
- <translation type="unfinished"/>
+ <translation>Kullanıcıyı Engelle</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
- <translation type="unfinished"/>
+ <translation>Bir kullanıcıyı engellediğinizde, ondan mesaj alamayacaksınız.&lt;br&gt;&lt;br&gt; %1&apos;i engellemek istediğinizden emin misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
- <translation type="unfinished"/>
+ <translation>At</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
- <translation type="unfinished"/>
+ <translation>Yasakla</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
- <translation type="unfinished"/>
+ <translation>Kullanıcıyı At</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
- <translation type="unfinished"/>
+ <translation>%1&apos;i &lt;b&gt;atmak&lt;/b&gt; istediğinizden emin misiniz? </translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
- <translation type="unfinished"/>
+ <translation>Kullanıcıyı Yasakla</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -172,22 +178,22 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="14"/>
<source>Room Window</source>
- <translation type="unfinished"/>
+ <translation>Oda Penceresi</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="27"/>
<source>Room Description</source>
- <translation type="unfinished"/>
+ <translation>Oda Açıklaması</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="47"/>
<source>Moderation...</source>
- <translation type="unfinished"/>
+ <translation>Moderasyon...</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.ui" line="57"/>
<source>Leave Room</source>
- <translation type="unfinished"/>
+ <translation>Odadan Ayrıl</translation>
</message>
</context>
<context>
@@ -200,7 +206,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="87"/>
<source>Disconnected</source>
- <translation type="unfinished"/>
+ <translation>Bağlantı kesildi</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/client_room.cpp" line="100"/>
@@ -392,17 +398,17 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="96"/>
<source>Preview</source>
- <translation type="unfinished"/>
+ <translation>Önizle</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="108"/>
<source>Resolution: 320*240</source>
- <translation type="unfinished"/>
+ <translation>Çözünürlük: 320*240</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="115"/>
<source>Click to preview</source>
- <translation type="unfinished"/>
+ <translation>Önizlemek için tıkla</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_camera.ui" line="140"/>
@@ -747,200 +753,235 @@ Bu seçenek belleğe yazma/okuma işlemlerindeki güvenlik kontrolünü kaldıra
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
- <translation type="unfinished"/>
+ <translation>Hata Ayıklayıcı</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>GDB Stub&apos;ı Etkinleştir</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Port:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Kütük Tutma</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Evrensel Kütük Filtresi</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>Konsolda Log&apos;u Göster</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Kütük Konumunu Aç</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Etkinleştirildiğinde log&apos;un boyut sınırı 100 MB&apos;tan 1 GB&apos;a çıkar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>Uzatılmış Hata Kaydını Etkinleştir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Arguments String</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Grafikler</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>Etkinleştirildiğinde, grafik API&apos;ı daha yavaş bir hata ayıklama moduna girer.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Grafik Hata Ayıklama Modunu Etkinleştir</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>İşaretlendiğinde Nsight Aftermath çökme dökümlerini etkinleştirir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>Nsight Aftermath&apos;ı Etkinleştir</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>İşaretlendiğinde Makro JIT derleyicisini devre dışı bırakır. Bu seçeneği etkinleştirmek oyunların yavaş çalışmasına neden olur.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Macro JIT&apos;i devre dışı bırak</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>Etkinleştirildiğinde, yuzu derlenen pipeline cache istatistiklerini log&apos;a kaydeder.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>Shader Geribildirimini Etkinleştir</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>İşaretlendiğinde shaderları döngü mantık değişimleri olmaksızın uygular</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>Döngü güvenliği kontrolünü devre dışı bırak</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Hata ayıklama</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>Detaylı Raporlama Hizmetini Etkinleştir</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
<source>Enable FS Access Log</source>
<translation>FS Erişim Kaydını Etkinleştir</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
+ <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
- <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>Detaylı Raporlama Hizmetini Etkinleştir</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Gelişmiş</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Kiosk (Quest) Modu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>CPU Hata Ayıklama Modu&apos;nu Etkinleştir</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>Hata Ayıklama Assert&apos;lerini Etkinleştir</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>Auto-Stub&apos;ı Etkinleştir</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation>Bütün Kontrolcü Türlerini Etkinleştir</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>Web Uygulamasını Devre Dışı Bırak</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Bu yuzu kapandığında otomatik olarak eski haline dönecektir.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation>Yeniden Başlatma Gerekli</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation>yuzu&apos;nun bu ayarı uygulayabilmesi için yeniden başlatılması gereklidir.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1249,7 +1290,7 @@ Bu seçenek belleğe yazma/okuma işlemlerindeki güvenlik kontrolünü kaldıra
<message>
<location filename="../../src/yuzu/configuration/configure_general.ui" line="88"/>
<source>Pause emulation when in background</source>
- <translation>Arka plana alındığında emülasyonu durdur</translation>
+ <translation>Arka plana alındığında emülasyonu duraklat</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_general.ui" line="95"/>
@@ -1536,7 +1577,7 @@ Bu seçenek belleğe yazma/okuma işlemlerindeki güvenlik kontrolünü kaldıra
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="78"/>
<source>Use VSync</source>
- <translation type="unfinished"/>
+ <translation>VSync Kullan</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="85"/>
@@ -1559,37 +1600,47 @@ Bu seçenek belleğe yazma/okuma işlemlerindeki güvenlik kontrolünü kaldıra
<translation>Hızlı GPU Saati Kullan (Hack)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Anisotropic Filtering:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>Otomatik</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Varsayılan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -1652,7 +1703,7 @@ Bu seçenek belleğe yazma/okuma işlemlerindeki güvenlik kontrolünü kaldıra
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="158"/>
<source>Home+%1</source>
- <translation type="unfinished"/>
+ <translation>Ev+%1</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="172"/>
@@ -1984,7 +2035,7 @@ Bu seçenek belleğe yazma/okuma işlemlerindeki güvenlik kontrolünü kaldıra
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2609"/>
<source>Ring Controller</source>
- <translation type="unfinished"/>
+ <translation>Ring Kontrolcüsü</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2623"/>
@@ -2081,7 +2132,7 @@ Bu seçenek belleğe yazma/okuma işlemlerindeki güvenlik kontrolünü kaldıra
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Sol Analog</translation>
</message>
@@ -2175,14 +2226,14 @@ Bu seçenek belleğe yazma/okuma işlemlerindeki güvenlik kontrolünü kaldıra
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2201,7 +2252,7 @@ Bu seçenek belleğe yazma/okuma işlemlerindeki güvenlik kontrolünü kaldıra
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Artı</translation>
</message>
@@ -2214,15 +2265,15 @@ Bu seçenek belleğe yazma/okuma işlemlerindeki güvenlik kontrolünü kaldıra
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2279,231 +2330,236 @@ Bu seçenek belleğe yazma/okuma işlemlerindeki güvenlik kontrolünü kaldıra
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Sağ Analog</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Temizle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[belirlenmedi]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>Tuş ayarla</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>Tuşları ters çevir</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Tuş ayarla</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>Ekseni ters çevir</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>Alt sınır ayarla</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>%0 ve %100 arasında bir değer seçin</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Analog Çubuğu Ayarla</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Tamama bastıktan sonra, joystikinizi önce yatay sonra dikey olarak hareket ettirin.
Eksenleri ters çevirmek için, önce joystickinizi dikey sonra yatay olarak hareket ettirin.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>Ölü Bölge: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>Düzenleyici Aralığı: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>İkili Joyconlar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Sol Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Sağ Joycon</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Handheld</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>GameCube Kontrolcüsü</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>Poke Ball Plus</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>NES Kontrolcüsü</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>SNES Kontrolcüsü</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>N64 Kontrolcüsü</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Sega Genesis</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
- <translation>Başlat / Durdur</translation>
+ <translation>Başlat / Duraklat</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>Kontrol Çubuğu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Çubuğu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Salla!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[bekleniyor]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Yeni Profil</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Bir profil ismi girin:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Kontrol Profili Oluştur</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>Girilen profil ismi geçerli değil!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>&quot;%1&quot; kontrol profili oluşturulamadı </translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Kontrol Profilini Kaldır</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>&quot;%1&quot; kontrol profili kaldırılamadı</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Kontrol Profilini Yükle</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>&quot;%1&quot; kontrol profili yüklenemedi</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Kontrol Profilini Kaydet</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>&quot;%1&quot; kontrol profili kaydedilemedi</translation>
</message>
@@ -2758,42 +2814,42 @@ Eksenleri ters çevirmek için, önce joystickinizi dikey sonra yatay olarak har
<translation>Geliştirici</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Eklentiler</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Genel</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Sistem</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Grafikler</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Gelişmiş Grafikler</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Ses</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Özellikler</translation>
</message>
@@ -2992,7 +3048,7 @@ Eksenleri ters çevirmek için, önce joystickinizi dikey sonra yatay olarak har
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="52"/>
<source>Ring Sensor Parameters</source>
- <translation type="unfinished"/>
+ <translation>Ring Sensör Parametreleri</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="84"/>
@@ -3505,47 +3561,47 @@ Eksenleri ters çevirmek için, önce joystickinizi dikey sonra yatay olarak har
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt; Kontrolcü girdilerini TAS-nx scriptleri ile aynı formatta okur. &lt;br/&gt;Daha detaylı bilgi için lütfen yuzu web sitesindeki &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt; yardım sayfasına&lt;/span&gt;&lt;/a&gt;bakınız.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>Hangi kısayolların Yeniden Oynatma/Kayıt fonksiyonunu kontrol ettiğini öğrenmek için Kısayol Ayarlarına bakın. (Yapılandır -&gt; Genel -&gt; Kısayollar)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>UYARI: Bu deneysel bir özelliktir.&lt;br/&gt; Halihazırdaki kusurlu eşzamanlama yöntemi sebebiyle, scriptleri mükemmel olarak oynatmayacaktır.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>Ayarlar</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>TAS özelliklerini Etkinleştir</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>Döngü komut dosyası</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>Yüklemeler sırasında yürütmeyi duraklat</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>Script Konumu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Konum</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3955,7 +4011,7 @@ Noktanın konumunu değiştirmek için sürükleyin ya da sayıların üstüne
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Doğrula</translation>
</message>
@@ -4042,7 +4098,7 @@ Noktanın konumunu değiştirmek için sürükleyin ya da sayıların üstüne
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>Belirlenmemiş</translation>
</message>
@@ -4057,17 +4113,36 @@ Noktanın konumunu değiştirmek için sürükleyin ya da sayıların üstüne
<translation>Token doğrulanmadı. Tokeninize yapılan değişiklik kaydedilmedi.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation>Doğrulanmadı, lütfen konfigürasyonu kaydetmeden önce Doğrula tuşuna basın</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>Doğrulanıyor...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation>Doğrulandı</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
+ <source>Verification failed</source>
+ <comment>Tooltip</comment>
+ <translation>Doğrulanma başarısız oldu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
<source>Verification failed</source>
<translation>Doğrulanma başarısız oldu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>Doğrulanma başarısız oldu. Kullanıcı adı ve tokeninizi doğru girdiğinizden ve internete bağlı olduğunuzdan.</translation>
</message>
@@ -4090,17 +4165,17 @@ Noktanın konumunu değiştirmek için sürükleyin ya da sayıların üstüne
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="14"/>
<source>Direct Connect</source>
- <translation type="unfinished"/>
+ <translation>Direkt Bağlan</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="33"/>
<source>IP Address</source>
- <translation type="unfinished"/>
+ <translation>IP Adresi</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="56"/>
<source>IP</source>
- <translation type="unfinished"/>
+ <translation>IP</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="63"/>
@@ -4110,7 +4185,7 @@ Noktanın konumunu değiştirmek için sürükleyin ya da sayıların üstüne
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="73"/>
<source>Port</source>
- <translation type="unfinished"/>
+ <translation>Port</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="80"/>
@@ -4120,516 +4195,516 @@ Noktanın konumunu değiştirmek için sürükleyin ya da sayıların üstüne
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="100"/>
<source>Nickname</source>
- <translation type="unfinished"/>
+ <translation>Lakap</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="114"/>
<source>Password</source>
- <translation type="unfinished"/>
+ <translation>Şifre</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="156"/>
<source>Connect</source>
- <translation type="unfinished"/>
+ <translation>Bağlan</translation>
</message>
</context>
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
- <translation type="unfinished"/>
+ <translation>Bağlanılıyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
- <translation type="unfinished"/>
+ <translation>Bağlan</translation>
</message>
</context>
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Yuzuyu geliştirmeye yardımcı olmak için &lt;/a&gt; anonim veri toplandı. &lt;br/&gt;&lt;br/&gt;Kullanım verinizi bizimle paylaşmak ister misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Telemetri</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
- <translation type="unfinished"/>
+ <translation>Bozuk Vulkan Kurulumu Algılandı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>Web Uygulaması Yükleniyor...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>Web Uygulamasını Devre Dışı Bırak</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>Şu anda derlenen shader miktarı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>Geçerli seçili çözünürlük ölçekleme çarpanı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Geçerli emülasyon hızı. %100&apos;den yüksek veya düşük değerler emülasyonun bir Switch&apos;den daha hızlı veya daha yavaş çalıştığını gösterir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Oyunun şuanda saniye başına kaç kare gösterdiği. Bu oyundan oyuna ve sahneden sahneye değişiklik gösterir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Bir Switch karesini emüle etmekte geçen zaman, karelimitleme ve v-sync hariç. Tam hız emülasyon için bu en çok 16,67 ms olmalı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>&amp;Son Dosyaları Temizle</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>&amp;Devam Et</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
- <translation>&amp;Durdur</translation>
+ <translation>&amp;Duraklat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>yuzu şu anda bir oyun çalıştırıyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Uyarı, Eski Oyun Formatı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Bu oyun için dekonstrükte ROM formatı kullanıyorsunuz, bu fromatın yerine NCA, NAX, XCI ve NSP formatları kullanılmaktadır. Dekonstrükte ROM formatları ikon, üst veri ve güncelleme desteği içermemektedir.&lt;br&gt;&lt;br&gt;Yuzu&apos;nun desteklediği çeşitli Switch formatları için&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;Wiki&apos;yi ziyaret edin&lt;/a&gt;. Bu mesaj yeniden gösterilmeyecektir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>ROM yüklenirken hata oluştu!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>Bu ROM biçimi desteklenmiyor.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Video çekirdeğini başlatılırken bir hata oluştu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu video çekirdeğini çalıştırırken bir hatayla karşılaştı. Bu sorun genellikle eski GPU sürücüleri sebebiyle ortaya çıkar. Daha fazla detay için lütfen log dosyasına bakın. Log dosyasını incelemeye dair daha fazla bilgi için lütfen bu sayfaya ulaşın: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Log dosyası nasıl yüklenir&lt;/a&gt;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>ROM yüklenirken hata oluştu! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;Lütfen dosyalarınızı yeniden dump etmek için&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu hızlı başlangıç kılavuzu&apos;nu&lt;/a&gt; takip edin.&lt;br&gt; Yardım için yuzu wiki&lt;/a&gt;veya yuzu Discord&apos;una&lt;/a&gt; bakabilirsiniz.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Bilinmeyen bir hata oluştu. Lütfen daha fazla detay için kütüğe göz atınız.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>Kayıt Verisi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Mod Verisi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>%1 klasörü açılırken hata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Klasör mevcut değil!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>Transfer Edilebilir Shader Cache&apos;ini Açarken Bir Hata Oluştu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>Bu oyun için shader cache konumu oluşturulamadı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>İçerikler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Güncelleme</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>Girdiyi Kaldır</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>%1 Adlı Oyunu Kaldırmak İstediğinize Emin Misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>Başarıyla Kaldırıldı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>Yüklenmiş oyun başarıyla kaldırıldı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>%1 Adlı Oyun Kaldırılırken Bir Hata Oluştu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>Asıl oyun NAND&apos;de kurulu değil ve kaldırılamaz.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>Yüklenmiş güncelleme başarıyla kaldırıldı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>Bu oyun için yüklenmiş bir güncelleme yok.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>Bu oyun için yüklenmiş bir DLC yok.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>%1 yüklenmiş DLC başarıyla kaldırıldı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>OpenGL Transfer Edilebilir Shader Cache&apos;ini Kaldırmak İstediğinize Emin Misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>Vulkan Transfer Edilebilir Shader Cache&apos;ini Kaldırmak İstediğinize Emin Misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>Tüm Transfer Edilebilir Shader Cache&apos;leri Kaldırmak İstediğinize Emin Misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>Oyuna Özel Yapılandırmayı Kaldırmak İstediğinize Emin Misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>Dosyayı Sil</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>Transfer Edilebilir Shader Cache Kaldırılırken Bir Hata Oluştu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>Bu oyun için oluşturulmuş bir shader cache yok.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>Transfer edilebilir shader cache başarıyla kaldırıldı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>Transfer edilebilir shader cache kaldırılamadı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>Transfer Edilebilir Shader Cache&apos;ler Kaldırılırken Bir Hata Oluştu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>Transfer edilebilir shader cacheler başarıyla kaldırıldı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>Transfer edilebilir shader cache konumu kaldırılamadı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>Oyuna Özel Yapılandırma Kaldırılırken Bir Hata Oluştu.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>Bu oyun için bir özel yapılandırma yok.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>Oyuna özel yapılandırma başarıyla kaldırıldı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>Oyuna özel yapılandırma kaldırılamadı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS Çıkartımı Başarısız!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>RomFS dosyaları kopyalanırken bir hata oluştu veya kullanıcı işlemi iptal etti.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>Full</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Çerçeve</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>RomFS Dump Modunu Seçiniz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Lütfen RomFS&apos;in nasıl dump edilmesini istediğinizi seçin.&lt;br&gt;&quot;Full&quot; tüm dosyaları yeni bir klasöre kopyalarken &lt;br&gt;&quot;skeleton&quot; sadece klasör yapısını oluşturur.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>%1 konumunda RomFS çıkarmaya yetecek alan yok. Lütfen yer açın ya da Emülasyon &gt; Yapılandırma &gt; Sistem &gt; Dosya Sistemi &gt; Dump konumu kısmından farklı bir çıktı konumu belirleyin.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>RomFS çıkartılıyor...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>İptal</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS Çıkartımı Başarılı!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>İşlem başarıyla tamamlandı.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>%1 Açılırken Bir Hata Oluştu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Klasör Seç</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Özellikler</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Oyun özellikleri yüklenemedi.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch Çalıştırılabilir Dosyası (%1);;Tüm Dosyalar (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Dosya Aç</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Çıkartılmış ROM klasörünü aç</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Geçersiz Klasör Seçildi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Seçtiğiniz klasör bir &quot;main&quot; dosyası içermiyor.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Yüklenilebilir Switch Dosyası (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submissions Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>Dosya Kur</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>%n dosya kaldı</numerusform><numerusform>%n dosya kaldı</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>&quot;%1&quot; dosyası kuruluyor...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>Kurulum Sonuçları</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>Olası çakışmaları önlemek için oyunları NAND&apos;e yüklememenizi tavsiye ediyoruz.
Lütfen bu özelliği sadece güncelleme ve DLC yüklemek için kullanın.</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>%n dosya güncel olarak yüklendi
@@ -4637,7 +4712,7 @@ Lütfen bu özelliği sadece güncelleme ve DLC yüklemek için kullanın.</tran
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n dosyanın üstüne yazıldı
@@ -4645,7 +4720,7 @@ Lütfen bu özelliği sadece güncelleme ve DLC yüklemek için kullanın.</tran
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n dosya yüklenemedi
@@ -4653,411 +4728,391 @@ Lütfen bu özelliği sadece güncelleme ve DLC yüklemek için kullanın.</tran
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Sistem Uygulaması</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Sistem Arşivi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Sistem Uygulama Güncellemesi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Yazılım Paketi (Tür A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Yazılım Paketi (Tür B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Oyun</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Oyun Güncellemesi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>Oyun DLC&apos;si</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Delta Başlık</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>NCA Kurulum Tipi Seçin...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Lütfen bu NCA dosyası için belirlemek istediğiniz başlık türünü seçiniz:
(Çoğu durumda, varsayılan olan &apos;Oyun&apos; kullanılabilir.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Kurulum Başarısız Oldu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>NCA için seçtiğiniz başlık türü geçersiz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Dosya Bulunamadı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Dosya &quot;%1&quot; Bulunamadı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>Tamam</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Kayıp yuzu Hesabı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Oyun uyumluluk test çalışması göndermek için öncelikle yuzu hesabınla giriş yapmanız gerekiyor.&lt;br&gt;&lt;br/&gt;Yuzu hesabınızla giriş yapmak için, Emülasyon &amp;gt; Yapılandırma &amp;gt; Web&apos;e gidiniz.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>URL açılırken bir hata oluştu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>URL &quot;%1&quot; açılamıyor.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>TAS kayıtta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>Oyuncu 1&apos;in dosyasının üstüne yazılsın mı?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>Geçersiz yapılandırma tespit edildi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>Handheld kontrolcü dock modunda kullanılamaz. Pro kontrolcü seçilecek.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>Hata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation>Aktif oyun amiibo beklemiyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation>Amiibo kaldırıldı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo Dosyası (%1);; Tüm Dosyalar (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Amiibo Yükle</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Amiibo veri dosyasını açarken hata</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>&quot;%1&quot; Amiibo dosyası okunamadı</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Amiibo veri dosyasını okurken hata</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Amiibo verisi tamamen okunamadı. %1 byte okunması bekleniyordu, fakat bunun sadece %2&apos;si okunabildi.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Amiibo verisi yüklenirken hata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Amiibo verisi yüklenemedi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Ekran Görüntüsü Al</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>PNG görüntüsü (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS durumu: %1%2 çalışıyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>TAS durumu: %1 kaydediliyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAS durumu: %1%2 boşta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>TAS durumu: Geçersiz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>&amp;Çalıştırmayı durdur</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Başlat</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>K&amp;aydetmeyi Durdur</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>K&amp;aydet</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>Oluşturuluyor: %n shader</numerusform><numerusform>Oluşturuluyor: %n shader</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>Ölçek: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Hız %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Hız: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>Oyun: %1 FPS (Sınırsız)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Oyun: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Kare: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU YÜKSEK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU EKSTREM</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>GPU HATASI</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>EN YAKIN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>BILINEAR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>BICUBIC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>GAUSYEN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>SCALEFORCE</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>NO AA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>Yüklemeye çalıştığınız oyun oynanmadan önce Switch&apos;inizden ek dosyaların alınmasını gerektiriyor.&lt;br/&gt;&lt;br/&gt;Bu dosyaları nasıl alacağınız hakkında daha fazla bilgi için, lütfen bu wiki sayfasına göz atınız: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Konsolunuzdan Sistem Arşivleri ve Shared Fontları Almak&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;oyun listesine geri dönmek ister misiniz? Emülasyona devam etmek çökmelere, kayıt dosyalarının bozulmasına veya başka hatalara sebep verebilir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>Yuzu bir Switch sistem arşivi bulamadı. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>Yuzu bir Switch sistem arşivi bulamadı: %1. %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Sistem Arşivi Bulunamadı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Sistem Arşivi Kayıp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>Yuzu Switch shared fontlarını bulamadı. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Shared Font&apos;lar Bulunamadı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Shared Font Kayıp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Önemli Hata</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>Yuzu önemli bir hatayla karşılaştı, lütfen daha fazla detay için kütüğe bakınız. Kütüğe erişmek hakkında daha fazla bilgi için, lütfen bu sayfaya göz atınız: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Log Dosyası Nasıl Yüklenir&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Oyun listesine geri dönmek ister misiniz? Emülasyona devam etmek çökmelere, kayıt dosyalarının bozulmasına veya başka hatalara sebep olabilir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>Önemli Bir Hatayla Karşılaşıldı</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Anahtar Yeniden Türetimini Onayla</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5074,37 +5129,37 @@ ve opsiyonel olarak yedekler alın.
Bu sizin otomatik oluşturulmuş anahtar dosyalarınızı silecek ve anahtar türetme modülünü tekrar çalıştıracak.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>Anahtarlar Kayıp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation>- BOOT0 Kayıp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation>- BCPKG2-1-Normal-Main Kayıp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation>- PRODINFO Kayıp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>Türeten Bileşenleri Kayıp</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>Şifreleme anahtarları eksik. &lt;br&gt;Lütfen takip edin&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu hızlı başlangıç kılavuzunu&lt;/a&gt;tüm anahtarlarınızı, aygıt yazılımınızı ve oyunlarınızı almada.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5113,39 +5168,39 @@ Bu sistem performansınıza bağlı olarak
bir dakika kadar zaman alabilir.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Anahtarlar Türetiliyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>RomFS Dump Hedefini Seçiniz</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Lütfen dump etmek istediğiniz RomFS&apos;i seçiniz.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>yuzu&apos;yu kapatmak istediğinizden emin misiniz?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Emülasyonu durdurmak istediğinizden emin misiniz? Kaydedilmemiş veriler kaybolur.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5464,22 +5519,22 @@ Screen.</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="14"/>
<source>Create Room</source>
- <translation type="unfinished"/>
+ <translation>Oda Oluştur</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="37"/>
<source>Room Name</source>
- <translation type="unfinished"/>
+ <translation>Oda Adı</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="51"/>
<source>Preferred Game</source>
- <translation type="unfinished"/>
+ <translation>Tercih Edilen Oyun</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="61"/>
<source>Max Players</source>
- <translation type="unfinished"/>
+ <translation>Maksimum Oyuncular</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="91"/>
@@ -5489,37 +5544,37 @@ Screen.</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="101"/>
<source>(Leave blank for open game)</source>
- <translation type="unfinished"/>
+ <translation>(Açık oyun için boş bırakın)</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="118"/>
<source>Password</source>
- <translation type="unfinished"/>
+ <translation>Şifre</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="125"/>
<source>Port</source>
- <translation type="unfinished"/>
+ <translation>Port</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="139"/>
<source>Room Description</source>
- <translation type="unfinished"/>
+ <translation>Oda Açıklaması</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="153"/>
<source>Load Previous Ban List</source>
- <translation type="unfinished"/>
+ <translation>Önceki Yasak Listesini Yükle</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="184"/>
<source>Public</source>
- <translation type="unfinished"/>
+ <translation>Herkese Açık</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="189"/>
<source>Unlisted</source>
- <translation type="unfinished"/>
+ <translation>Gizli</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="197"/>
@@ -5530,12 +5585,12 @@ Screen.</source>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>Hata</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5544,11 +5599,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
- <translation type="unfinished"/>
+ <translation>Sesi Sustur/Aç</translation>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5570,112 +5626,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
- <translation type="unfinished"/>
+ <translation>Ana Pencere</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Ekran Görüntüsü Al</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
- <translation type="unfinished"/>
+ <translation>Sürdür/Emülasyonu duraklat</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
- <translation type="unfinished"/>
+ <translation>Tam Ekrandan Çık</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
- <translation type="unfinished"/>
+ <translation>Yuzu&apos;dan çık</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Tam Ekran</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Dosya Aç</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
- <translation type="unfinished"/>
+ <translation>Emülasyonu Yeniden Başlat</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
- <translation type="unfinished"/>
+ <translation>Emülasyonu Durdur</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
- <translation type="unfinished"/>
+ <translation>TAS Kaydet</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
- <translation type="unfinished"/>
+ <translation>TAS Sıfırla</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
- <translation type="unfinished"/>
+ <translation>TAS Başlat/Durdur</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5762,7 +5817,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="32"/>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="39"/>
<source>Nickname</source>
- <translation type="unfinished"/>
+ <translation>Lakap</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="59"/>
@@ -5772,12 +5827,12 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="66"/>
<source>Search</source>
- <translation type="unfinished"/>
+ <translation>Ara</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="76"/>
<source>Games I Own</source>
- <translation type="unfinished"/>
+ <translation>Sahip Olduğum Oyunlar</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="83"/>
@@ -5790,44 +5845,44 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
- <translation type="unfinished"/>
+ <translation>Şifre:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
- <translation type="unfinished"/>
+ <translation>Oda Adı</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
- <translation type="unfinished"/>
+ <translation>Tercih Edilen Oyun</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Oyuncular</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
- <translation type="unfinished"/>
+ <translation>Yenileniyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
- <translation type="unfinished"/>
+ <translation>Listeyi Yenile</translation>
</message>
</context>
<context>
@@ -5990,22 +6045,22 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/main.ui" line="262"/>
<source>Create Room</source>
- <translation type="unfinished"/>
+ <translation>Oda Oluştur</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="270"/>
<source>Leave Room</source>
- <translation type="unfinished"/>
+ <translation>Odadan Ayrıl</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="275"/>
<source>Direct Connect to Room</source>
- <translation type="unfinished"/>
+ <translation>Odaya Direkt Bağlan</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="283"/>
<source>Show Current Room</source>
- <translation type="unfinished"/>
+ <translation>Şu Anki Odayı Göster</translation>
</message>
<message>
<location filename="../../src/yuzu/main.ui" line="291"/>
@@ -6091,23 +6146,23 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="6"/>
<source>Moderation</source>
- <translation type="unfinished"/>
+ <translation>Moderasyon</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="20"/>
<source>Ban List</source>
- <translation type="unfinished"/>
+ <translation>Ban Listesi</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="41"/>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="73"/>
<source>Refreshing</source>
- <translation type="unfinished"/>
+ <translation>Yenileniyor</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="51"/>
<source>Unban</source>
- <translation type="unfinished"/>
+ <translation>Yasağı kaldır</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="40"/>
@@ -6117,22 +6172,22 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="41"/>
<source>Type</source>
- <translation type="unfinished"/>
+ <translation>Tip</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="83"/>
<source>Forum Username</source>
- <translation type="unfinished"/>
+ <translation>Forum Kullanıcı Adı</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="88"/>
<source>IP Address</source>
- <translation type="unfinished"/>
+ <translation>IP Adresi</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="95"/>
<source>Refresh</source>
- <translation type="unfinished"/>
+ <translation>Yenile</translation>
</message>
</context>
<context>
@@ -6141,18 +6196,18 @@ Debug Message: </source>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="47"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="91"/>
<source>Current connection status</source>
- <translation type="unfinished"/>
+ <translation>Anlık bağlantı durumu</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="48"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="94"/>
<source>Not Connected. Click here to find a room!</source>
- <translation type="unfinished"/>
+ <translation>Bağlantı Yok. Oda bulmak için buraya basın!</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Bağlandı</translation>
</message>
@@ -6160,7 +6215,7 @@ Debug Message: </source>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="99"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="128"/>
<source>Not Connected</source>
- <translation type="unfinished"/>
+ <translation>Bağlantı Yok</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="181"/>
@@ -6174,9 +6229,9 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
- <translation type="unfinished"/>
+ <translation>Yeni Mesaj Alındı</translation>
</message>
</context>
<context>
@@ -6184,27 +6239,27 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="11"/>
<source>Username is not valid. Must be 4 to 20 alphanumeric characters.</source>
- <translation type="unfinished"/>
+ <translation>Kullanıcı adı geçersiz. 4 ile 20 alfasayısal karakter arasında olmalı.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="13"/>
<source>Room name is not valid. Must be 4 to 20 alphanumeric characters.</source>
- <translation type="unfinished"/>
+ <translation>Oda adı geçersiz. 4 ile 20 alfasayısal karakter arasında olmalı.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="15"/>
<source>Username is already in use or not valid. Please choose another.</source>
- <translation type="unfinished"/>
+ <translation>Kullanıcı adı halihazırda kullanılıyor. Lütfen başka bir kullanıcı adı seçin.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="17"/>
<source>IP is not a valid IPv4 address.</source>
- <translation type="unfinished"/>
+ <translation>IP geçerli bir IPv4 adresi değil.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="19"/>
<source>Port must be a number between 0 to 65535.</source>
- <translation type="unfinished"/>
+ <translation>Port 0 ile 65535 arasında bir numara olmalı.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="20"/>
@@ -6214,7 +6269,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="24"/>
<source>Unable to find an internet connection. Check your internet settings.</source>
- <translation type="unfinished"/>
+ <translation>İnternet bağlantısı bulunamadı. İnternet ayarlarınızı kontrol edin.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="26"/>
@@ -6224,17 +6279,17 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="30"/>
<source>Unable to connect to the room because it is already full.</source>
- <translation type="unfinished"/>
+ <translation>Oda halihazırda dolu olduğundan dolayı katılınamadı.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="32"/>
<source>Creating a room failed. Please retry. Restarting yuzu might be necessary.</source>
- <translation type="unfinished"/>
+ <translation>Odayı oluşturma başarısız oldu. Lütfen tekrar deneyin. Yuzu&apos;yu yeniden başlatmak gerekebilir.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="34"/>
<source>The host of the room has banned you. Speak with the host to unban you or try a different room.</source>
- <translation type="unfinished"/>
+ <translation>Oda yöneticisi sizi odadan yasakladı. Yasağı kaldırmak için yönetici ile konuşun ya da başka bir oda deneyin.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="37"/>
@@ -6244,7 +6299,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="39"/>
<source>Incorrect password.</source>
- <translation type="unfinished"/>
+ <translation>Yanlış şifre.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="40"/>
@@ -6254,17 +6309,17 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="43"/>
<source>Connection to room lost. Try to reconnect.</source>
- <translation type="unfinished"/>
+ <translation>Odaya bağlantı kesildi. Yeniden bağlanmayı dene.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="45"/>
<source>You have been kicked by the room host.</source>
- <translation type="unfinished"/>
+ <translation>Oda yöneticisi seni odadan çıkardı.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="47"/>
<source>IP address is already in use. Please choose another.</source>
- <translation type="unfinished"/>
+ <translation>IP adresi halihazırda kullanılıyor. Lütfen başka bir IP adresi seçin.</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/message.cpp" line="49"/>
@@ -6278,22 +6333,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
- <source>Leave Room</source>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation>Oyun halihazırda çalışıyor</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
+ <source>Leave Room</source>
+ <translation>Odadan Ayrıl</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
- <translation type="unfinished"/>
+ <translation>Bağlantı kesildi</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6301,7 +6373,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>Hata</translation>
</message>
@@ -6344,7 +6416,7 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/configuration/configure_input_player_widget.cpp" line="1575"/>
<source>START/PAUSE</source>
- <translation>BAŞLAT/DURDUR</translation>
+ <translation>BAŞLAT/DURAKLAT</translation>
</message>
</context>
<context>
@@ -6352,17 +6424,17 @@ p, li { white-space: pre-wrap; }
<message>
<location filename="../../src/yuzu/multiplayer/lobby_p.h" line="230"/>
<source>%1 is not playing a game</source>
- <translation type="unfinished"/>
+ <translation>%1 şu anda oyun oynamıyor</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby_p.h" line="232"/>
<source>%1 is playing %2</source>
- <translation type="unfinished"/>
+ <translation>%1 %2&apos;yi oynuyor</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
- <translation type="unfinished"/>
+ <translation>Şu anda oyun oynamıyor</translation>
</message>
<message>
<location filename="../../src/yuzu/game_list_p.h" line="242"/>
@@ -6415,7 +6487,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[belirlenmedi]</translation>
</message>
@@ -6430,10 +6502,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Eksen %1%2</translation>
</message>
@@ -6447,9 +6519,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[bilinmeyen]</translation>
</message>
@@ -6614,15 +6686,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[geçersiz]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation>%1%2Hat %3</translation>
</message>
@@ -6630,35 +6702,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation>%1%2Eksen %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation>%1%2Eksen %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2Hareket %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2Tuş %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[kullanılmayan]</translation>
</message>
@@ -6699,7 +6771,7 @@ p, li { white-space: pre-wrap; }
<translation>Ekstra</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/languages/uk.ts b/dist/languages/uk.ts
new file mode 100644
index 000000000..66a3ac96e
--- /dev/null
+++ b/dist/languages/uk.ts
@@ -0,0 +1,7321 @@
+<?xml version="1.0" ?><!DOCTYPE TS><TS version="2.1" language="uk" sourcelanguage="en_US">
+<context>
+ <name>AboutDialog</name>
+ <message>
+ <location filename="../../src/yuzu/aboutdialog.ui" line="14"/>
+ <source>About yuzu</source>
+ <translation>Про yuzu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/aboutdialog.ui" line="72"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:28pt;&quot;&gt;yuzu&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:28pt;&quot;&gt;yuzu&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/aboutdialog.ui" line="85"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;%1 (%2)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;%1 (%2)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/aboutdialog.ui" line="98"/>
+ <source>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:12pt;&quot;&gt;yuzu is an experimental open-source emulator for the Nintendo Switch licensed under GPLv3.0+.&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:12pt;&quot;&gt;This software should not be used to play games you have not legally obtained.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;Ubuntu&apos;; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:12pt;&quot;&gt;yuzu є експериментальним емулятором Nintendo Switch з відкритим кодом ліцензований під GPLv3.0+.&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:&apos;MS Shell Dlg 2&apos;; font-size:8pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:12pt;&quot;&gt;Це програмне забезпечення не слід використовувати для ігор, які ви отримали незаконним шляхом.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/aboutdialog.ui" line="130"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Website&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Source Code&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Contributors&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;License&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://yuzu-emu.org/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Веб-сайт&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Вихідний код&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/graphs/contributors&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Вкладники&lt;/span&gt;&lt;/a&gt; | &lt;a href=&quot;https://github.com/yuzu-emu/yuzu/blob/master/LICENSE.txt&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;Ліцензія&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/aboutdialog.ui" line="146"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:7pt;&quot;&gt;&amp;quot;Nintendo Switch&amp;quot; is a trademark of Nintendo. yuzu is not affiliated with Nintendo in any way.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:7pt;&quot;&gt;&amp;quot;Nintendo Switch&amp;quot; є торговою маркою Nintendo. yuzu не пов&apos;язаний з Nintendo у будь-якому вигляді.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>CalibrationConfigurationDialog</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="23"/>
+ <source>Communicating with the server...</source>
+ <translation>Зв&apos;язок із сервером...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="24"/>
+ <source>Cancel</source>
+ <translation>Скасувати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="43"/>
+ <source>Touch the top left corner &lt;br&gt;of your touchpad.</source>
+ <translation>Торкніться верхнього лівого кута &lt;br&gt; вашого тачпаду.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="46"/>
+ <source>Now touch the bottom right corner &lt;br&gt;of your touchpad.</source>
+ <translation>Тепер торкніться правого нижнього кута &lt;br&gt; вашого тачпаду.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="49"/>
+ <source>Configuration completed!</source>
+ <translation>Налаштування завершено!</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="57"/>
+ <source>OK</source>
+ <translation>ОК</translation>
+ </message>
+</context>
+<context>
+ <name>ChatRoom</name>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.ui" line="14"/>
+ <source>Room Window</source>
+ <translation>Вікно кімнати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.ui" line="40"/>
+ <source>Send Chat Message</source>
+ <translation>Надіслати повідомлення в чат</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.ui" line="47"/>
+ <source>Send Message</source>
+ <translation>Надіслати повідомлення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="181"/>
+ <source>Members</source>
+ <translation>Члени</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
+ <source>%1 has joined</source>
+ <translation>%1 приєднався</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
+ <source>%1 has left</source>
+ <translation>%1 вийшов</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
+ <source>%1 has been kicked</source>
+ <translation>%1 вигнано</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="327"/>
+ <source>%1 has been banned</source>
+ <translation>%1 заблоковано</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="330"/>
+ <source>%1 has been unbanned</source>
+ <translation>%1 розблоковано</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="446"/>
+ <source>View Profile</source>
+ <translation>Переглянути профіль</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="459"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <source>Block Player</source>
+ <translation>Заблокувати гравця</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
+ <translation>Коли ви блокуєте гравця, ви більше не отримуватиме від нього повідомлення у чаті. &lt;br&gt;&lt;br&gt;Ви впевнені що бажаєте заблокувати %1?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
+ <source>Kick</source>
+ <translation>Вигнати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="484"/>
+ <source>Ban</source>
+ <translation>Заблокувати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="488"/>
+ <source>Kick Player</source>
+ <translation>Вигнати гравця</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="489"/>
+ <source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
+ <translation>Ви впевнені що бажаєте &lt;b&gt;вигнати&lt;/b&gt; %1?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="497"/>
+ <source>Ban Player</source>
+ <translation>Заблокувати гравця</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="498"/>
+ <source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
+
+This would ban both their forum username and their IP address.</source>
+ <translation>Ви впевнені що бажаєте &lt;b&gt;вигнати і заблокувати&lt;/b&gt; %1?
+
+Ця дія заблокує ім&apos;я користувача на форумі та IP-адресу.</translation>
+ </message>
+</context>
+<context>
+ <name>ClientRoom</name>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/client_room.ui" line="14"/>
+ <source>Room Window</source>
+ <translation>Вікно кімнати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/client_room.ui" line="27"/>
+ <source>Room Description</source>
+ <translation>Опис кімнати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/client_room.ui" line="47"/>
+ <source>Moderation...</source>
+ <translation>Модерація...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/client_room.ui" line="57"/>
+ <source>Leave Room</source>
+ <translation>Залишити кімнату</translation>
+ </message>
+</context>
+<context>
+ <name>ClientRoomWindow</name>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/client_room.cpp" line="78"/>
+ <source>Connected</source>
+ <translation>З&apos;єднано</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/client_room.cpp" line="87"/>
+ <source>Disconnected</source>
+ <translation>Роз&apos;єднано</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/client_room.cpp" line="100"/>
+ <source>%1 - %2 (%3/%4 members) - connected</source>
+ <translation>%1 - %2 (%3/%4 члени) - з&apos;єднано</translation>
+ </message>
+</context>
+<context>
+ <name>CompatDB</name>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="20"/>
+ <source>Report Compatibility</source>
+ <translation>Повідомити про сумісність</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="27"/>
+ <location filename="../../src/yuzu/compatdb.ui" line="63"/>
+ <source>Report Game Compatibility</source>
+ <translation>Повідомити про сумісність гри</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="36"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Should you choose to submit a test case to the &lt;/span&gt;&lt;a href=&quot;https://yuzu-emu.org/game/&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;yuzu Compatibility List&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;, The following information will be collected and displayed on the site:&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Hardware Information (CPU / GPU / Operating System)&lt;/li&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Which version of yuzu you are running&lt;/li&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;The connected yuzu account&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;Якщо ви бажаєте надіслати звіт до &lt;/span&gt;&lt;a href=&quot;https://yuzu-emu.org/game/&quot;&gt;&lt;span style=&quot; font-size:10pt; text-decoration: underline; color:#0000ff;&quot;&gt;списку сумісності yuzu&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt;, наступна інформація буде зібрана та відображена на сайті:&lt;/span&gt;&lt;/p&gt;&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Інформація про залізо (ЦП / ГП / Операційна система)&lt;/li&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Версія yuzu&lt;/li&gt;&lt;li style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Підключений акаунт yuzu&lt;/li&gt;&lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="72"/>
+ <source>Perfect</source>
+ <translation>Ідеально</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="79"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Game functions flawlessly with no audio or graphical glitches.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Гра працює ідеально, без звукових чи графічних артефактів.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="89"/>
+ <source>Great</source>
+ <translation>Чудово</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="96"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Game functions with minor graphical or audio glitches and is playable from start to finish. May require some workarounds.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Гра працює з невеликими графічними або звуковими артефактами та може бути пройдена від початку до кінця. Можуть знадобитися обхідні шляхи.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="106"/>
+ <source>Okay</source>
+ <translation>Добре</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="113"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Game functions with major graphical or audio glitches, but game is playable from start to finish with workarounds.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Гра працює зі суттєвими графічними або звуковими артефактами, але з обхідними шляхами може бути пройдена.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="123"/>
+ <source>Bad</source>
+ <translation>Погано</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="130"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Game functions, but with major graphical or audio glitches. Unable to progress in specific areas due to glitches even with workarounds.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Гра працює, але з суттєвими графічними чи звуковими артефактами. У деяких місцях неможливо пройти навіть із обхідними шляхами.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="140"/>
+ <source>Intro/Menu</source>
+ <translation>Вступ/Меню</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="147"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Game is completely unplayable due to major graphical or audio glitches. Unable to progress past the Start Screen.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;У гру неможливо грати через серйозні графічні або звукові артефакти. Неможливо просунутися далі за стартове меню.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="157"/>
+ <source>Won&apos;t Boot</source>
+ <translation>Не запускається</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="170"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The game crashes when attempting to startup.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Гра вилітає при спробі запуску.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="182"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Independent of speed or performance, how well does this game play from start to finish on this version of yuzu?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Незалежно від швидкості або продуктивності, наскільки добре ця гра працює від початку до кінця у поточній версії yuzu?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.ui" line="206"/>
+ <source>Thank you for your submission!</source>
+ <translation>Дякуємо за ваш звіт!</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.cpp" line="58"/>
+ <source>Submitting</source>
+ <translation>Надсилання</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.cpp" line="71"/>
+ <source>Communication error</source>
+ <translation>Помилка з&apos;єднання</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.cpp" line="72"/>
+ <source>An error occurred while sending the Testcase</source>
+ <translation>Сталася помилка під час надсилання звіту</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/compatdb.cpp" line="74"/>
+ <source>Next</source>
+ <translation>Далі</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureAudio</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_audio.ui" line="14"/>
+ <location filename="../../src/yuzu/configuration/configure_audio.ui" line="20"/>
+ <source>Audio</source>
+ <translation>Аудіо</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_audio.ui" line="28"/>
+ <source>Output Engine:</source>
+ <translation>Рушій виводу:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_audio.ui" line="42"/>
+ <source>Output Device</source>
+ <translation>Пристрій виводу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_audio.ui" line="56"/>
+ <source>Input Device</source>
+ <translation>Пристрій вводу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_audio.ui" line="84"/>
+ <source>Use global volume</source>
+ <translation>Використовувати загальну гучність</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_audio.ui" line="89"/>
+ <source>Set volume:</source>
+ <translation>Встановити гучність:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_audio.ui" line="97"/>
+ <source>Volume:</source>
+ <translation>Гучність</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_audio.ui" line="142"/>
+ <source>0 %</source>
+ <translation>0 %</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_audio.cpp" line="108"/>
+ <source>%1%</source>
+ <comment>Volume percentage (e.g. 50%)</comment>
+ <translation>%1%</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureCamera</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_camera.ui" line="14"/>
+ <source>Configure Infrared Camera</source>
+ <translation>Налаштування інфрачервоної камери</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_camera.ui" line="26"/>
+ <source>Select where the image of the emulated camera comes from. It may be a virtual camera or a real camera.</source>
+ <translation>Виберіть, звідки береться зображення емульованої камери. Це може бути віртуальна або реальна камера.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_camera.ui" line="52"/>
+ <source>Camera Image Source:</source>
+ <translation>Джерело зображення камери:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_camera.ui" line="71"/>
+ <source>Input device:</source>
+ <translation>Пристрій вводу:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_camera.ui" line="96"/>
+ <source>Preview</source>
+ <translation>Попередній перегляд</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_camera.ui" line="108"/>
+ <source>Resolution: 320*240</source>
+ <translation>Роздільна здатність: 320*240</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_camera.ui" line="115"/>
+ <source>Click to preview</source>
+ <translation>Натисніть для попереднього перегляду</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_camera.ui" line="140"/>
+ <source>Restore Defaults</source>
+ <translation>Значення за замовчуванням</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_camera.cpp" line="135"/>
+ <source>Auto</source>
+ <translation>Авто</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureCpu</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="17"/>
+ <source>CPU</source>
+ <translation>ЦП</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="25"/>
+ <source>General</source>
+ <translation>Загальні</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="34"/>
+ <source>Accuracy:</source>
+ <translation>Точність:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="42"/>
+ <source>Auto</source>
+ <translation>Авто</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="47"/>
+ <source>Accurate</source>
+ <translation>Точно</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="52"/>
+ <source>Unsafe</source>
+ <translation>Небезпечно</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="57"/>
+ <source>Paranoid (disables most optimizations)</source>
+ <translation>Параноїк (відключає більшість оптимізацій)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="68"/>
+ <source>We recommend setting accuracy to &quot;Auto&quot;.</source>
+ <translation>Ми рекомендуємо встановити точність на &quot;Авто&quot;.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="85"/>
+ <source>Unsafe CPU Optimization Settings</source>
+ <translation>Небезпечні налаштування оптимізації ЦП</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="91"/>
+ <source>These settings reduce accuracy for speed.</source>
+ <translation>Ці налаштування зменшують точність заради швидкості. </translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="101"/>
+ <source>
+ &lt;div&gt;This option improves speed by reducing accuracy of fused-multiply-add instructions on CPUs without native FMA support.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="106"/>
+ <source>Unfuse FMA (improve performance on CPUs without FMA)</source>
+ <translation>Не використовувати FMA (покращує продуктивність на ЦП без FMA)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="113"/>
+ <source>
+ &lt;div&gt;This option improves the speed of some approximate floating-point functions by using less accurate native approximations.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="118"/>
+ <source>Faster FRSQRTE and FRECPE</source>
+ <translation>Прискорені FRSQRTE та FRECPE</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="125"/>
+ <source>
+ &lt;div&gt;This option improves the speed of 32 bits ASIMD floating-point functions by running with incorrect rounding modes.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="130"/>
+ <source>Faster ASIMD instructions (32 bits only)</source>
+ <translation>Швидші інструкції ASIMD (лише 32 біт)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="137"/>
+ <source>
+ &lt;div&gt;This option improves speed by removing NaN checking. Please note this also reduces accuracy of certain floating-point instructions.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="142"/>
+ <source>Inaccurate NaN handling</source>
+ <translation>Неправильна обробка NaN</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="149"/>
+ <source>
+ &lt;div&gt;This option improves speed by eliminating a safety check before every memory read/write in guest. Disabling it may allow a game to read/write the emulator's memory.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="154"/>
+ <source>Disable address space checks</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="161"/>
+ <source>
+ &lt;div&gt;This option improves speed by relying only on the semantics of cmpxchg to ensure safety of exclusive access instructions. Please note this may result in deadlocks and other race conditions.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="166"/>
+ <source>Ignore global monitor</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu.ui" line="191"/>
+ <source>CPU settings are available only when game is not running.</source>
+ <translation>Налаштування ЦП недоступні, поки запущена гра.</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureCpuDebug</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="17"/>
+ <source>CPU</source>
+ <translation>ЦП</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="25"/>
+ <source>Toggle CPU Optimizations</source>
+ <translation>Увімкнути оптимізації ЦП</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="31"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;For debugging only.&lt;/span&gt;&lt;br/&gt;If you&apos;re not sure what these do, keep all of these enabled. &lt;br/&gt;These settings, when disabled, only take effect when CPU Debugging is enabled. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Тільки для налагодження.&lt;/span&gt;&lt;br/&gt;Якщо ви не впевнені в тому, що вони роблять, залиште всі ці параметри увімкненими. &lt;br/&gt;Коли їх вимкнено, ці параметри набувають чинності лише за увімкненого налагодження ЦП. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="41"/>
+ <source>
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it inlines accesses to PageTable::pointers into emitted code.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="48"/>
+ <source>Enable inline page tables</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="55"/>
+ <source>
+ &lt;div&gt;This optimization avoids dispatcher lookups by allowing emitted basic blocks to jump directly to other basic blocks if the destination PC is static.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="60"/>
+ <source>Enable block linking</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="67"/>
+ <source>
+ &lt;div&gt;This optimization avoids dispatcher lookups by keeping track potential return addresses of BL instructions. This approximates what happens with a return stack buffer on a real CPU.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="72"/>
+ <source>Enable return stack buffer</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="79"/>
+ <source>
+ &lt;div&gt;Enable a two-tiered dispatch system. A faster dispatcher written in assembly has a small MRU cache of jump destinations is used first. If that fails, dispatch falls back to the slower C++ dispatcher.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="84"/>
+ <source>Enable fast dispatcher</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="91"/>
+ <source>
+ &lt;div&gt;Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="96"/>
+ <source>Enable context elimination</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="103"/>
+ <source>
+ &lt;div&gt;Enables IR optimizations that involve constant propagation.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="108"/>
+ <source>Enable constant propagation</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="115"/>
+ <source>
+ &lt;div&gt;Enables miscellaneous IR optimizations.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="120"/>
+ <source>Enable miscellaneous optimizations</source>
+ <translation>Увімкнути різні оптимізації</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="127"/>
+ <source>
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;When enabled, a misalignment is only triggered when an access crosses a page boundary.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;When disabled, a misalignment is triggered on all misaligned accesses.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="133"/>
+ <source>Enable misalignment check reduction</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="140"/>
+ <source>
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it causes guest memory reads/writes to be done directly into memory and make use of Host's MMU.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Disabling this forces all memory accesses to use Software MMU Emulation.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="147"/>
+ <source>Enable Host MMU Emulation (general memory instructions)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="154"/>
+ <source>
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up exclusive memory accesses by the guest program.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it causes guest exclusive memory reads/writes to be done directly into memory and make use of Host's MMU.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Disabling this forces all exclusive memory accesses to use Software MMU Emulation.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="161"/>
+ <source>Enable Host MMU Emulation (exclusive memory instructions)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="168"/>
+ <source>
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up exclusive memory accesses by the guest program.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it reduces the overhead of fastmem failure of exclusive memory accesses.&lt;/div&gt;
+ </source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="174"/>
+ <source>Enable recompilation of exclusive memory instructions</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_cpu_debug.ui" line="199"/>
+ <source>CPU settings are available only when game is not running.</source>
+ <translation>Налаштування ЦП доступні тільки тоді, коли гру не запущено.</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureDebug</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
+ <source>Debugger</source>
+ <translation>Налагоджувач</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
+ <source>Enable GDB Stub</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
+ <source>Port:</source>
+ <translation>Порт:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
+ <source>Logging</source>
+ <translation>Журналювання</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
+ <source>Global Log Filter</source>
+ <translation>Глобальний фільтр журналів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
+ <source>Show Log in Console</source>
+ <translation>Показувати журнал у консолі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
+ <source>Open Log Location</source>
+ <translation>Відкрити папку для журналів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
+ <source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
+ <translation>Якщо увімкнено, максимальний розмір журналу збільшується зі 100 МБ до 1 ГБ</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
+ <source>Enable Extended Logging**</source>
+ <translation>Увімкнути розширене ведення журналу**</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
+ <source>Homebrew</source>
+ <translation>Homebrew</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
+ <source>Arguments String</source>
+ <translation>Рядок аргументів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
+ <source>Graphics</source>
+ <translation>Графіка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
+ <source>When checked, the graphics API enters a slower debugging mode</source>
+ <translation>Якщо увімкнено, графічний API переходить у повільніший режим налагодження</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
+ <source>Enable Graphics Debugging</source>
+ <translation>Увімкнути налагодження графіки</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
+ <source>When checked, it enables Nsight Aftermath crash dumps</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
+ <source>Enable Nsight Aftermath</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
+ <source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
+ <translation>Якщо ввімкнено, буде дампити всі оригінальні шейдери асемблера з кешу шейдерів на диску або гри як знайдені</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
+ <source>Dump Game Shaders</source>
+ <translation>Дамп ігрових шейдерів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
+ <source>When checked, it will dump all the macro programs of the GPU</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
+ <source>Dump Maxwell Macros</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
+ <source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
+ <source>Disable Macro JIT</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
+ <source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
+ <translation>Якщо увімкнено, yuzu записуватиме статистику про скомпільований кеш конвеєра</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
+ <source>Enable Shader Feedback</source>
+ <translation>Увімкнути зворотний зв&apos;язок про шейдери</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
+ <source>When checked, it executes shaders without loop logic changes</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
+ <source>Disable Loop safety checks</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
+ <source>Debugging</source>
+ <translation>Налагодження</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
+ <source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
+ <source>Advanced</source>
+ <translation>Розширені</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
+ <source>Kiosk (Quest) Mode</source>
+ <translation>Режим кіоску (Квест)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
+ <source>Enable CPU Debugging</source>
+ <translation>Увімкнути налагодження ЦП</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
+ <source>Enable Debug Asserts</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
+ <source>Enable Auto-Stub**</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
+ <source>Enable All Controller Types</source>
+ <translation>Увімкнути всі типи контролерів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
+ <source>Disable Web Applet</source>
+ <translation>Вимкнути веб-аплет</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation>Дозволяє yuzu перевіряти наявність робочого середовища Vulkan під час запуску програми. Вимкніть цю опцію, якщо це викликає проблеми з тим, що зовнішні програми бачать yuzu.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation>Виконувати перевірку Vulkan під час запуску</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
+ <source>**This will be reset automatically when yuzu closes.</source>
+ <translation>**Це буде автоматично скинуто після закриття yuzu.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation>Потрібен перезапуск</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation>yuzu потрібно перезапустити, щоб застосувати це налаштування.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation>Веб-аплет не скомпільовано</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>ConfigureDebugController</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug_controller.ui" line="14"/>
+ <source>Configure Debug Controller</source>
+ <translation>Налаштування налагоджувального контролера</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug_controller.ui" line="40"/>
+ <source>Clear</source>
+ <translation>Очистити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug_controller.ui" line="47"/>
+ <source>Defaults</source>
+ <translation>За замовчуванням</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureDebugTab</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug_tab.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug_tab.ui" line="17"/>
+ <location filename="../../src/yuzu/configuration/configure_debug_tab.cpp" line="16"/>
+ <source>Debug</source>
+ <translation>Налагодження</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug_tab.cpp" line="17"/>
+ <source>CPU</source>
+ <translation>ЦП</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureDialog</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure.ui" line="20"/>
+ <source>yuzu Configuration</source>
+ <translation>Налаштування yuzu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="52"/>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="156"/>
+ <source>Audio</source>
+ <translation>Аудіо</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="53"/>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="154"/>
+ <source>CPU</source>
+ <translation>ЦП</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="54"/>
+ <source>Debug</source>
+ <translation>Налагодження</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="55"/>
+ <source>Filesystem</source>
+ <translation>Файлова система</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="56"/>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="150"/>
+ <source>General</source>
+ <translation>Загальні</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="155"/>
+ <source>Graphics</source>
+ <translation>Графіка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="58"/>
+ <source>GraphicsAdvanced</source>
+ <translation>ГрафікаРозширені</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="59"/>
+ <source>Hotkeys</source>
+ <translation>Гарячі клавіші</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="157"/>
+ <source>Controls</source>
+ <translation>Керування</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="61"/>
+ <source>Profiles</source>
+ <translation>Профілі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="62"/>
+ <source>Network</source>
+ <translation>Мережа</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="152"/>
+ <source>System</source>
+ <translation>Система</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="64"/>
+ <source>Game List</source>
+ <translation>Список ігор</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_dialog.cpp" line="65"/>
+ <source>Web</source>
+ <translation>Мережа</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureFilesystem</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="17"/>
+ <source>Filesystem</source>
+ <translation>Файлова система</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="25"/>
+ <source>Storage Directories</source>
+ <translation>Каталоги зберігання</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="31"/>
+ <source>NAND</source>
+ <translation>NAND</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="38"/>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="114"/>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="143"/>
+ <source>...</source>
+ <translation>...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="51"/>
+ <source>SD Card</source>
+ <translation>SD карта</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="84"/>
+ <source>Gamecard</source>
+ <translation>Картридж</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="90"/>
+ <source>Path</source>
+ <translation>Шлях</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="100"/>
+ <source>Inserted</source>
+ <translation>Вставлений</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="107"/>
+ <source>Current Game</source>
+ <translation>Поточна гра</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="124"/>
+ <source>Patch Manager</source>
+ <translation>Керування патчами</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="152"/>
+ <source>Dump Decompressed NSOs</source>
+ <translation>Дамп розпакованих NSO</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="159"/>
+ <source>Dump ExeFS</source>
+ <translation>Дамп ExeFS</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="168"/>
+ <source>Mod Load Root</source>
+ <translation>Папка з модами</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="175"/>
+ <source>Dump Root</source>
+ <translation>Корінь дампу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="201"/>
+ <source>Caching</source>
+ <translation>Кешування</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="209"/>
+ <source>Cache Game List Metadata</source>
+ <translation>Кешувати метадані списку ігор</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.ui" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="131"/>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="135"/>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="140"/>
+ <source>Reset Metadata Cache</source>
+ <translation>Скинути кеш метаданих</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="93"/>
+ <source>Select Emulated NAND Directory...</source>
+ <translation>Виберіть папку для емульованого NAND...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="96"/>
+ <source>Select Emulated SD Directory...</source>
+ <translation>Виберіть папку для емульованого SD...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="99"/>
+ <source>Select Gamecard Path...</source>
+ <translation>Оберіть папку для картриджів...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="102"/>
+ <source>Select Dump Directory...</source>
+ <translation>Оберіть папку для дампів...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="105"/>
+ <source>Select Mod Load Directory...</source>
+ <translation>Оберіть папку для модів...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="132"/>
+ <source>The metadata cache is already empty.</source>
+ <translation>Кеш метаданих вже порожній.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="136"/>
+ <source>The operation completed successfully.</source>
+ <translation>Операція завершилася успішно.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_filesystem.cpp" line="141"/>
+ <source>The metadata cache couldn&apos;t be deleted. It might be in use or non-existent.</source>
+ <translation>Кеш метаданих не можна видалити. Можливо, він використовується або відсутній.</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureGeneral</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.ui" line="17"/>
+ <location filename="../../src/yuzu/configuration/configure_general.ui" line="25"/>
+ <source>General</source>
+ <translation>Загальні</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.ui" line="35"/>
+ <source>Limit Speed Percent</source>
+ <translation>Обмеження відсотка швидкості</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.ui" line="42"/>
+ <source>%</source>
+ <translation>%</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.ui" line="60"/>
+ <source>Multicore CPU Emulation</source>
+ <translation>Багатоядерна емуляція ЦП</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.ui" line="67"/>
+ <source>Extended memory layout (6GB DRAM)</source>
+ <translation>Розширене компонування пам&apos;яті (6 ГБ DRAM)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.ui" line="74"/>
+ <source>Confirm exit while emulation is running</source>
+ <translation>Підтверджувати вихід під час емуляції</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.ui" line="81"/>
+ <source>Prompt for user on game boot</source>
+ <translation>Запитувати користувача під час запуску гри</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.ui" line="88"/>
+ <source>Pause emulation when in background</source>
+ <translation>Призупиняти емуляцію у фоновому режимі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.ui" line="95"/>
+ <source>Mute audio when in background</source>
+ <translation>Приглушити звук у фоновому режимі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.ui" line="102"/>
+ <source>Hide mouse on inactivity</source>
+ <translation>Приховування миші при бездіяльності</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.ui" line="144"/>
+ <source>Reset All Settings</source>
+ <translation>Скинути всі налаштування</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.cpp" line="68"/>
+ <source>yuzu</source>
+ <translation>yuzu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_general.cpp" line="69"/>
+ <source>This reset all settings and remove all per-game configurations. This will not delete game directories, profiles, or input profiles. Proceed?</source>
+ <translation>Це скине всі налаштування і видалить усі конфігурації під окремі ігри. При цьому не будуть видалені шляхи до ігор, профілів або профілів вводу. Продовжити?</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureGraphics</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="17"/>
+ <source>Graphics</source>
+ <translation>Графіка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="25"/>
+ <source>API Settings</source>
+ <translation>Налаштування API</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="64"/>
+ <source>Shader Backend:</source>
+ <translation>Бекенд шейдерів:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="92"/>
+ <source>Device:</source>
+ <translation>Пристрій:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="120"/>
+ <source>API:</source>
+ <translation>API:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="156"/>
+ <source>Graphics Settings</source>
+ <translation>Налаштування графіки</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="162"/>
+ <source>Use disk pipeline cache</source>
+ <translation>Використовувати кеш конвеєра на диску</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="169"/>
+ <source>Use asynchronous GPU emulation</source>
+ <translation>Використовувати асинхронну емуляцію ГП</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="176"/>
+ <source>Accelerate ASTC texture decoding</source>
+ <translation>Прискорення декодування текстур ASTC</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="198"/>
+ <source>NVDEC emulation:</source>
+ <translation>Емуляція NVDEC:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="206"/>
+ <source>No Video Output</source>
+ <translation>Відсутність відеовиходу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="211"/>
+ <source>CPU Video Decoding</source>
+ <translation>Декодування відео на ЦП</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="216"/>
+ <source>GPU Video Decoding (Default)</source>
+ <translation>Декодування відео на ГП (за замовчуванням)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="242"/>
+ <source>Fullscreen Mode:</source>
+ <translation>Повноекранний режим:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="250"/>
+ <source>Borderless Windowed</source>
+ <translation>Вікно без рамок</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="255"/>
+ <source>Exclusive Fullscreen</source>
+ <translation>Ексклюзивний повноекранний</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="281"/>
+ <source>Aspect Ratio:</source>
+ <translation>Співвідношення сторін:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="289"/>
+ <source>Default (16:9)</source>
+ <translation>За замовчуванням (16:9)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="294"/>
+ <source>Force 4:3</source>
+ <translation>Змусити 4:3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="299"/>
+ <source>Force 21:9</source>
+ <translation>Змусити 21:9</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="304"/>
+ <source>Force 16:10</source>
+ <translation>Змусити 16:10</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="309"/>
+ <source>Stretch to Window</source>
+ <translation>Розтягнути до вікна</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="335"/>
+ <source>Resolution:</source>
+ <translation>Роздільна здатність:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="343"/>
+ <source>0.5X (360p/540p) [EXPERIMENTAL]</source>
+ <translation>0.5X (360p/540p) [ЕКСПЕРИМЕНТАЛЬНЕ]</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="348"/>
+ <source>0.75X (540p/810p) [EXPERIMENTAL]</source>
+ <translation>0.75X (540p/810p) [ЕКСПЕРИМЕНТАЛЬНЕ]</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="353"/>
+ <source>1X (720p/1080p)</source>
+ <translation>1X (720p/1080p)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="358"/>
+ <source>2X (1440p/2160p)</source>
+ <translation>2X (1440p/2160p)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="363"/>
+ <source>3X (2160p/3240p)</source>
+ <translation>3X (2160p/3240p)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="368"/>
+ <source>4X (2880p/4320p)</source>
+ <translation>4X (2880p/4320p)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="373"/>
+ <source>5X (3600p/5400p)</source>
+ <translation>5X (3600p/5400p)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="378"/>
+ <source>6X (4320p/6480p)</source>
+ <translation>6X (4320p/6480p)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="404"/>
+ <source>Window Adapting Filter:</source>
+ <translation>Фільтр адаптації вікна:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="412"/>
+ <source>Nearest Neighbor</source>
+ <translation>Найближчий сусід</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="417"/>
+ <source>Bilinear</source>
+ <translation>Білінійне</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="422"/>
+ <source>Bicubic</source>
+ <translation>Бікубічне</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="427"/>
+ <source>Gaussian</source>
+ <translation>Гауса</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="432"/>
+ <source>ScaleForce</source>
+ <translation>ScaleForce</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="437"/>
+ <source>AMD FidelityFX™️ Super Resolution (Vulkan Only)</source>
+ <translation>AMD FidelityFX™️ Super Resolution (Лише для Vulkan)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="463"/>
+ <source>Anti-Aliasing Method:</source>
+ <translation>Метод згладжування:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="471"/>
+ <source>None</source>
+ <translation>Вимкнено</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="476"/>
+ <source>FXAA</source>
+ <translation>FXAA</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="511"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="521"/>
+ <source>Use global background color</source>
+ <translation>Використовувати глобальний фоновий колір</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="526"/>
+ <source>Set background color:</source>
+ <translation>Встановити фоновий колір:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.ui" line="534"/>
+ <source>Background Color:</source>
+ <translation>Фоновий колір:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics.cpp" line="33"/>
+ <source>GLASM (Assembly Shaders, NVIDIA Only)</source>
+ <translation>GLASM (асемблерні шейдери, лише для NVIDIA)</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureGraphicsAdvanced</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="17"/>
+ <source>Advanced</source>
+ <translation>Розширені</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="25"/>
+ <source>Advanced Graphics Settings</source>
+ <translation>Розширені налаштування графіки</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="46"/>
+ <source>Accuracy Level:</source>
+ <translation>Рівень точності:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="75"/>
+ <source>VSync prevents the screen from tearing, but some graphics cards have lower performance with VSync enabled. Keep it enabled if you don&apos;t notice a performance difference.</source>
+ <translation>Вертикальна синхронізація запобігає розривам екрана, але деякі відеокарти мають нижчу продуктивність при вертикальній синхронізації. Залишайте увімкненим, якщо ви не помічаєте різниці в продуктивності.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="78"/>
+ <source>Use VSync</source>
+ <translation>Використувати вертикальну сінхронізацію</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="85"/>
+ <source>Enables asynchronous shader compilation, which may reduce shader stutter. This feature is experimental.</source>
+ <translation>Вмикає асинхронну компіляцію шейдерів, що зменшить зависання через шейдери. Функція є експериментальною.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="88"/>
+ <source>Use asynchronous shader building (Hack)</source>
+ <translation>Використовувати асинхронну побудову шейдерів (хак)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="95"/>
+ <source>Enables Fast GPU Time. This option will force most games to run at their highest native resolution.</source>
+ <translation>Вмикає функцію Fast GPU Time. Цей параметр змусить більшість ігор працювати в максимальній рідній роздільній здатності.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="98"/>
+ <source>Use Fast GPU Time (Hack)</source>
+ <translation>Увімкнути Fast GPU Time (Хак)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation>Вмикає песимістичне очищення буферів. Ця опція змушує промивати немодифіковані буфери, що може знизити продуктивність.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation>Використовувати песимістичне очищення буферів (Хак)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
+ <source>Anisotropic Filtering:</source>
+ <translation>Анізотропна фільтрація:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <source>Automatic</source>
+ <translation>Автоматично</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <source>Default</source>
+ <translation>За замовчуванням</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <source>2x</source>
+ <translation>2x</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <source>4x</source>
+ <translation>4x</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
+ <source>8x</source>
+ <translation>8x</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
+ <source>16x</source>
+ <translation>16x</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureHotkeys</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.ui" line="14"/>
+ <source>Hotkey Settings</source>
+ <translation>Налаштування гарячих клавіш</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.ui" line="17"/>
+ <source>Hotkeys</source>
+ <translation>Гарячі клавіші</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.ui" line="25"/>
+ <source>Double-click on a binding to change it.</source>
+ <translation>Натисніть двічі на прив&apos;язці, щоб змінити її.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.ui" line="45"/>
+ <source>Clear All</source>
+ <translation>Очистити все</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.ui" line="52"/>
+ <source>Restore Defaults</source>
+ <translation>Відновити значення за замовчуванням.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="98"/>
+ <source>Action</source>
+ <translation>Дія</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="98"/>
+ <source>Hotkey</source>
+ <translation>Гаряча клавіша</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="98"/>
+ <source>Controller Hotkey</source>
+ <translation>Гаряча клавіша контролера</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="164"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="379"/>
+ <source>Conflicting Key Sequence</source>
+ <translation>Конфліктуюча комбінація клавіш</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="139"/>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="165"/>
+ <source>The entered key sequence is already assigned to: %1</source>
+ <translation>Введена комбінація вже призначена до: %1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="158"/>
+ <source>Home+%1</source>
+ <translation>Home+%1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="172"/>
+ <source>[waiting]</source>
+ <translation>[очікування]</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="242"/>
+ <source>Invalid</source>
+ <translation>Неприпустимо</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="343"/>
+ <source>Restore Default</source>
+ <translation>Відновити значення за замовчуванням</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="344"/>
+ <source>Clear</source>
+ <translation>Очистити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="365"/>
+ <source>Conflicting Button Sequence</source>
+ <translation>Конфліктуюче поєднання кнопок</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="366"/>
+ <source>The default button sequence is already assigned to: %1</source>
+ <translation>Типова комбінація кнопок вже призначена до: %1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_hotkeys.cpp" line="380"/>
+ <source>The default key sequence is already assigned to: %1</source>
+ <translation>Типова комбінація клавіш вже призначена до: %1</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureInput</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="14"/>
+ <source>ConfigureInput</source>
+ <translation>НалаштуванняВводу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="42"/>
+ <source>Player 1</source>
+ <translation>Гравець 1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="47"/>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="50"/>
+ <source>Player 2</source>
+ <translation>Гравець 2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="55"/>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="58"/>
+ <source>Player 3</source>
+ <translation>Гравець 3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="66"/>
+ <source>Player 4</source>
+ <translation>Гравець 4</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="74"/>
+ <source>Player 5</source>
+ <translation>Гравець 5</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="79"/>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="82"/>
+ <source>Player 6</source>
+ <translation>Гравець 6</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="87"/>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="90"/>
+ <source>Player 7</source>
+ <translation>Гравець 7</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="95"/>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="98"/>
+ <source>Player 8</source>
+ <translation>Гравець 8</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="106"/>
+ <source>Advanced</source>
+ <translation>Розширені</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="138"/>
+ <source>Console Mode</source>
+ <translation>Режим консолі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="159"/>
+ <source>Docked</source>
+ <translation>У док-станції</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="169"/>
+ <source>Handheld</source>
+ <translation>Портативний</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="179"/>
+ <source>Vibration</source>
+ <translation>Вібрація</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="215"/>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="261"/>
+ <source>Configure</source>
+ <translation>Налаштувати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="225"/>
+ <source>Motion</source>
+ <translation>Рух</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="296"/>
+ <source>Controllers</source>
+ <translation>Контролери</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="324"/>
+ <source>1</source>
+ <translation>1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="365"/>
+ <source>2</source>
+ <translation>2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="375"/>
+ <source>3</source>
+ <translation>3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="385"/>
+ <source>4</source>
+ <translation>4</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="395"/>
+ <source>5</source>
+ <translation>5</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="405"/>
+ <source>6</source>
+ <translation>6</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="415"/>
+ <source>7</source>
+ <translation>7</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="425"/>
+ <source>8</source>
+ <translation>8</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="435"/>
+ <source>Connected</source>
+ <translation>З&apos;єднано</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="494"/>
+ <source>Defaults</source>
+ <translation>За замовчуванням</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input.ui" line="537"/>
+ <source>Clear</source>
+ <translation>Очистити</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureInputAdvanced</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="14"/>
+ <source>Configure Input</source>
+ <translation>Налаштування вводу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="74"/>
+ <source>Joycon Colors</source>
+ <translation>Кольори Joy-Con&apos;ів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="125"/>
+ <source>Player 1</source>
+ <translation>Гравець 1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="164"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="450"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="754"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1040"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1365"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1651"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1955"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2241"/>
+ <source>L Body</source>
+ <translation>Лівий контролер</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="219"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="505"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="809"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1095"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1420"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1706"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2010"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2296"/>
+ <source>L Button</source>
+ <translation>Кнопка L</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="295"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="581"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="885"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1171"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1496"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1782"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2086"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2372"/>
+ <source>R Body</source>
+ <translation>Правий контролер</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="350"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="636"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="940"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1226"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1551"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1837"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2141"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2427"/>
+ <source>R Button</source>
+ <translation>Кнопка R</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="411"/>
+ <source>Player 2</source>
+ <translation>Гравець 2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="715"/>
+ <source>Player 3</source>
+ <translation>Гравець 3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1001"/>
+ <source>Player 4</source>
+ <translation>Гравець 4</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1326"/>
+ <source>Player 5</source>
+ <translation>Гравець 5</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1612"/>
+ <source>Player 6</source>
+ <translation>Гравець 6</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="1916"/>
+ <source>Player 7</source>
+ <translation>Гравець 7</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2202"/>
+ <source>Player 8</source>
+ <translation>Гравець 8</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2533"/>
+ <source>Emulated Devices</source>
+ <translation>Емульовані пристрої</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2545"/>
+ <source>Keyboard</source>
+ <translation>Клавіатура</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2558"/>
+ <source>Mouse</source>
+ <translation>Миша</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2565"/>
+ <source>Touchscreen</source>
+ <translation>Сенсорний екран</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2588"/>
+ <source>Advanced</source>
+ <translation>Розширені</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2595"/>
+ <source>Debug Controller</source>
+ <translation>Налагоджувальний контролер</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2602"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2616"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2630"/>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2743"/>
+ <source>Configure</source>
+ <translation>Налаштувати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2609"/>
+ <source>Ring Controller</source>
+ <translation>Контролер Ring</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2623"/>
+ <source>Infrared Camera</source>
+ <translation>Інфрачервона камера</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2640"/>
+ <source>Other</source>
+ <translation>Інше</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2652"/>
+ <source>Emulate Analog with Keyboard Input</source>
+ <translation>Емуляція аналогового вводу з клавіатури</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2659"/>
+ <source>Requires restarting yuzu</source>
+ <translation>Потребує перезапуску yuzu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2668"/>
+ <source>Enable XInput 8 player support (disables web applet)</source>
+ <translation>Увімкнути підтримку 8-ми гравців на XInput (відключає веб-аплет)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2681"/>
+ <source>Enable UDP controllers (not needed for motion)</source>
+ <translation>Увімкнути UDP контролери (не обов&apos;язково для руху)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2694"/>
+ <source>Controller navigation</source>
+ <translation>Навігація контролера</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2707"/>
+ <source>Enable mouse panning</source>
+ <translation>Увімкнути панорамування миші</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2714"/>
+ <source>Mouse sensitivity</source>
+ <translation>Чутливість миші</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2720"/>
+ <source>%</source>
+ <translation>%</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_advanced.ui" line="2736"/>
+ <source>Motion / Touch</source>
+ <translation>Рух і сенсор</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureInputPlayer</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="14"/>
+ <source>Configure Input</source>
+ <translation>Налаштування вводу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="63"/>
+ <source>Connect Controller</source>
+ <translation>Підключити контролер</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="100"/>
+ <source>Input Device</source>
+ <translation>Пристрій вводу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="156"/>
+ <source>Profile</source>
+ <translation>Профіль</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="196"/>
+ <source>Save</source>
+ <translation>Зберегти</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="212"/>
+ <source>New</source>
+ <translation>Новий</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="228"/>
+ <source>Delete</source>
+ <translation>Видалити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <source>Left Stick</source>
+ <translation>Лівий міні-джойстик</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="349"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="391"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="925"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="964"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2583"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2622"/>
+ <source>Up</source>
+ <translation>Вгору</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="422"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="461"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="995"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1034"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2069"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2653"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2692"/>
+ <source>Left</source>
+ <translation>Вліво</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="471"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="510"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1044"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1083"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2118"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2702"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2741"/>
+ <source>Right</source>
+ <translation>Вправо</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="553"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="592"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1126"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1165"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2784"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2823"/>
+ <source>Down</source>
+ <translation>Вниз</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="623"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2854"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2893"/>
+ <source>Pressed</source>
+ <translation>Натиснення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="672"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="711"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2903"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2942"/>
+ <source>Modifier</source>
+ <translation>Модифікатор</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="721"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2952"/>
+ <source>Range</source>
+ <translation>Діапазон</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="754"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2985"/>
+ <source>%</source>
+ <translation>%</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="797"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="3025"/>
+ <source>Deadzone: 0%</source>
+ <translation>Мертва зона: 0%</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="821"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="3049"/>
+ <source>Modifier Range: 0%</source>
+ <translation>Діапазон модифікатора: 0%</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="867"/>
+ <source>D-Pad</source>
+ <translation>Кнопки напрямків</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
+ <source>L</source>
+ <translation>L</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <source>ZL</source>
+ <translation>ZL</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1426"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1465"/>
+ <source>Minus</source>
+ <translation>Мінус</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1475"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1514"/>
+ <source>Capture</source>
+ <translation>Захоплення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
+ <source>Plus</source>
+ <translation>Плюс</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1594"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1633"/>
+ <source>Home</source>
+ <translation>Home</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
+ <source>R</source>
+ <translation>R</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <source>ZR</source>
+ <translation>ZR</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1873"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1912"/>
+ <source>SL</source>
+ <translation>SL</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1922"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1961"/>
+ <source>SR</source>
+ <translation>SR</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2030"/>
+ <source>Motion 1</source>
+ <translation>Рух 1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2079"/>
+ <source>Motion 2</source>
+ <translation>Рух 2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2170"/>
+ <source>Face Buttons</source>
+ <translation>Кнопки A/B/X/Y</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2228"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2267"/>
+ <source>X</source>
+ <translation>X</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2298"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2337"/>
+ <source>Y</source>
+ <translation>Y</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2347"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2386"/>
+ <source>A</source>
+ <translation>A</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2429"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2468"/>
+ <source>B</source>
+ <translation>B</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <source>Right Stick</source>
+ <translation>Правий міні-джойстик</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
+ <source>Clear</source>
+ <translation>Очистити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
+ <source>[not set]</source>
+ <translation>[не задано]</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
+ <source>Invert button</source>
+ <translation>Інвертувати кнопку</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>Переключити кнопку</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
+ <source>Invert axis</source>
+ <translation>Інвертувати осі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
+ <source>Set threshold</source>
+ <translation>Встановити поріг</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
+ <source>Choose a value between 0% and 100%</source>
+ <translation>Оберіть значення між 0% і 100%</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation>Переключити осі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
+ <source>Set gyro threshold</source>
+ <translation>Встановити поріг гіроскопа</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
+ <source>Map Analog Stick</source>
+ <translation>Задати аналоговий міні-джойстик</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
+ <source>After pressing OK, first move your joystick horizontally, and then vertically.
+To invert the axes, first move your joystick vertically, and then horizontally.</source>
+ <translation>Після натискання на ОК, рухайте ваш міні-джойстик горизонтально, а потім вертикально.
+Щоб інвертувати осі, спочатку рухайте ваш міні-джойстик вертикально, а потім горизонтально.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
+ <source>Center axis</source>
+ <translation>Центрувати осі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
+ <source>Deadzone: %1%</source>
+ <translation>Мертва зона: %1%</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
+ <source>Modifier Range: %1%</source>
+ <translation>Діапазон модифікатора: %1%</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
+ <source>Pro Controller</source>
+ <translation>Контролер Pro</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
+ <source>Dual Joycons</source>
+ <translation>Подвійні Joy-Con&apos;и</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
+ <source>Left Joycon</source>
+ <translation>Лівий Joy-Con</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
+ <source>Right Joycon</source>
+ <translation>Правий Joy-Con</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
+ <source>Handheld</source>
+ <translation>Портативний</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
+ <source>GameCube Controller</source>
+ <translation>Контролер GameCube</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
+ <source>Poke Ball Plus</source>
+ <translation>Poke Ball Plus</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
+ <source>NES Controller</source>
+ <translation>Контролер NES</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
+ <source>SNES Controller</source>
+ <translation>Контролер SNES</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
+ <source>N64 Controller</source>
+ <translation>Контролер N64</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
+ <source>Sega Genesis</source>
+ <translation>Sega Genesis</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
+ <source>Start / Pause</source>
+ <translation>Старт / Пауза</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
+ <source>Z</source>
+ <translation>Z</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
+ <source>Control Stick</source>
+ <translation>Міні-джойстик керування</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
+ <source>C-Stick</source>
+ <translation>C-Джойстик</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
+ <source>Shake!</source>
+ <translation>Потрусіть!</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
+ <source>[waiting]</source>
+ <translation>[очікування]</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
+ <source>New Profile</source>
+ <translation>Новий профіль</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
+ <source>Enter a profile name:</source>
+ <translation>Введіть ім&apos;я профілю:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
+ <source>Create Input Profile</source>
+ <translation>Створити профіль контролю</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <source>The given profile name is not valid!</source>
+ <translation>Задане ім&apos;я профілю недійсне!</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
+ <source>Failed to create the input profile &quot;%1&quot;</source>
+ <translation>Не вдалося створити профіль контролю &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
+ <source>Delete Input Profile</source>
+ <translation>Видалити профіль контролю</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
+ <source>Failed to delete the input profile &quot;%1&quot;</source>
+ <translation>Не вдалося видалити профіль контролю &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
+ <source>Load Input Profile</source>
+ <translation>Завантажити профіль контролю</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
+ <source>Failed to load the input profile &quot;%1&quot;</source>
+ <translation>Не вдалося завантажити профіль контролю &quot;%1&quot;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
+ <source>Save Input Profile</source>
+ <translation>Зберегти профіль контролю</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
+ <source>Failed to save the input profile &quot;%1&quot;</source>
+ <translation>Не вдалося зберегти профіль контролю &quot;%1&quot;</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureInputProfileDialog</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_profile_dialog.ui" line="14"/>
+ <source>Create Input Profile</source>
+ <translation>Створити профіль контролю</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_profile_dialog.ui" line="40"/>
+ <source>Clear</source>
+ <translation>Очистити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_profile_dialog.ui" line="47"/>
+ <source>Defaults</source>
+ <translation>За замовчуванням</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureMotionTouch</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="6"/>
+ <source>Configure Motion / Touch</source>
+ <translation>Налаштування руху та сенсора</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="15"/>
+ <source>Touch</source>
+ <translation>Сенсор</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="23"/>
+ <source>UDP Calibration:</source>
+ <translation>Калібрація UDP:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="30"/>
+ <source>(100, 50) - (1800, 850)</source>
+ <translation>(100, 50) - (1800, 850)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="46"/>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="73"/>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="243"/>
+ <source>Configure</source>
+ <translation>Налаштувати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="57"/>
+ <source>Touch from button profile:</source>
+ <translation>Торкніться з профілю кнопки:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="85"/>
+ <source>CemuhookUDP Config</source>
+ <translation>Налаштування CemuhookUDP</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="91"/>
+ <source>You may use any Cemuhook compatible UDP input source to provide motion and touch input.</source>
+ <translation>Ви можете використовувати будь-яке сумісне з Cemuhook джерело UDP сигналу для руху і сенсора.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="134"/>
+ <source>Server:</source>
+ <translation>Сервер:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="161"/>
+ <source>Port:</source>
+ <translation>Порт:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="188"/>
+ <source>Learn More</source>
+ <translation>Дізнатися більше</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="201"/>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="266"/>
+ <source>Test</source>
+ <translation>Тест</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="214"/>
+ <source>Add Server</source>
+ <translation>Додати сервер</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.ui" line="247"/>
+ <source>Remove Server</source>
+ <translation>Видалити сервер</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="87"/>
+ <source>&lt;a href=&apos;https://yuzu-emu.org/wiki/using-a-controller-or-android-phone-for-motion-or-touch-input&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn More&lt;/span&gt;&lt;/a&gt;</source>
+ <translation>&lt;a href=&apos;https://yuzu-emu.org/wiki/using-a-controller-or-android-phone-for-motion-or-touch-input&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Дізнатися більше&lt;/span&gt;&lt;/a&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="169"/>
+ <source>%1:%2</source>
+ <translation>%1:%2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="174"/>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="178"/>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="182"/>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="288"/>
+ <source>yuzu</source>
+ <translation>yuzu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="174"/>
+ <source>Port number has invalid characters</source>
+ <translation>Номер порту містить неприпустимі символи</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="178"/>
+ <source>Port has to be in range 0 and 65353</source>
+ <translation>Порт повинен бути в районі від 0 до 65353</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="182"/>
+ <source>IP address is not valid</source>
+ <translation>IP-адреса недійсна</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="188"/>
+ <source>This UDP server already exists</source>
+ <translation>Цей UDP сервер уже існує</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="194"/>
+ <source>Unable to add more than 8 servers</source>
+ <translation>Неможливо додати більше 8 серверів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="210"/>
+ <source>Testing</source>
+ <translation>Тестування</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="226"/>
+ <source>Configuring</source>
+ <translation>Налаштування</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="257"/>
+ <source>Test Successful</source>
+ <translation>Тест успішний</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="258"/>
+ <source>Successfully received data from the server.</source>
+ <translation>Успішно отримано інформацію із сервера</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="260"/>
+ <source>Test Failed</source>
+ <translation>Тест провалено</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="261"/>
+ <source>Could not receive valid data from the server.&lt;br&gt;Please verify that the server is set up correctly and the address and port are correct.</source>
+ <translation>Не вдалося отримати дійсні дані з сервера.&lt;br&gt;Переконайтеся, що сервер правильно налаштований, а також перевірте адресу та порт.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_motion_touch.cpp" line="289"/>
+ <source>UDP Test or calibration configuration is in progress.&lt;br&gt;Please wait for them to finish.</source>
+ <translation>Тест UDP або калібрація в процесі.&lt;br&gt;Будь ласка, зачекайте завершення.</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureNetwork</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_network.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_network.ui" line="17"/>
+ <source>Network</source>
+ <translation>Мережа</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_network.ui" line="25"/>
+ <source>General</source>
+ <translation>Загальні</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_network.ui" line="34"/>
+ <source>Network Interface</source>
+ <translation>Інтерфейс мережі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_network.cpp" line="15"/>
+ <source>None</source>
+ <translation>Нічого</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigurePerGame</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.ui" line="12"/>
+ <source>Dialog</source>
+ <translation>Діалог</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.ui" line="26"/>
+ <source>Info</source>
+ <translation>Інформація</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.ui" line="85"/>
+ <source>Name</source>
+ <translation>Назва</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.ui" line="92"/>
+ <source>Title ID</source>
+ <translation>Ідентифікатор гри</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.ui" line="129"/>
+ <source>Filename</source>
+ <translation>Ім&apos;я файлу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.ui" line="156"/>
+ <source>Format</source>
+ <translation>Формат</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.ui" line="163"/>
+ <source>Version</source>
+ <translation>Версія</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.ui" line="170"/>
+ <source>Size</source>
+ <translation>Розмір</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.ui" line="177"/>
+ <source>Developer</source>
+ <translation>Розробник</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
+ <source>Add-Ons</source>
+ <translation>Доповнення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <source>General</source>
+ <translation>Загальні</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <source>System</source>
+ <translation>Система</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <source>CPU</source>
+ <translation>ЦП</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <source>Graphics</source>
+ <translation>Графіка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <source>Adv. Graphics</source>
+ <translation>Розш. Графіка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <source>Audio</source>
+ <translation>Аудіо</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
+ <source>Properties</source>
+ <translation>Властивості</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configuration_shared.cpp" line="91"/>
+ <source>Use global configuration (%1)</source>
+ <translation>Використовувати глобальне налаштування (%1)</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigurePerGameAddons</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game_addons.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game_addons.ui" line="17"/>
+ <source>Add-Ons</source>
+ <translation>Доповнення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game_addons.cpp" line="46"/>
+ <source>Patch Name</source>
+ <translation>Назва патчу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_per_game_addons.cpp" line="47"/>
+ <source>Version</source>
+ <translation>Версія</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureProfileManager</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="17"/>
+ <source>Profiles</source>
+ <translation>Профілі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="25"/>
+ <source>Profile Manager</source>
+ <translation>Керування профілями</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="42"/>
+ <source>Current User</source>
+ <translation>Поточний користувач</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="80"/>
+ <source>Username</source>
+ <translation>Ім&apos;я користувача</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="110"/>
+ <source>Set Image</source>
+ <translation>Обрати зображення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="130"/>
+ <source>Add</source>
+ <translation>Додати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="140"/>
+ <source>Rename</source>
+ <translation>Перейменувати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="150"/>
+ <source>Remove</source>
+ <translation>Видалити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.ui" line="162"/>
+ <source>Profile management is available only when game is not running.</source>
+ <translation>Керування профілями недоступне, поки запущена гра.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="52"/>
+ <source>%1
+%2</source>
+ <comment>%1 is the profile username, %2 is the formatted UUID (e.g. 00112233-4455-6677-8899-AABBCCDDEEFF))</comment>
+ <translation>%1
+%2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="70"/>
+ <source>Enter Username</source>
+ <translation>Введіть ім&apos;я користувача</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="133"/>
+ <source>Users</source>
+ <translation>Користувачі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="195"/>
+ <source>Enter a username for the new user:</source>
+ <translation>Введіть ім&apos;я користувача для нового профілю:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="215"/>
+ <source>Enter a new username:</source>
+ <translation>Введіть нове ім&apos;я користувача:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="240"/>
+ <source>Confirm Delete</source>
+ <translation>Підтвердити видалення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="241"/>
+ <source>You are about to delete user with name &quot;%1&quot;. Are you sure?</source>
+ <translation>Ви збираєтеся видалити користувача &quot;%1&quot;. Ви впевнені?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="268"/>
+ <source>Select User Image</source>
+ <translation>Оберіть зображення користувача</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="269"/>
+ <source>JPEG Images (*.jpg *.jpeg)</source>
+ <translation>Зображення JPEG (*.jpg *.jpeg)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="278"/>
+ <source>Error deleting image</source>
+ <translation>Помилка під час видалення зображення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="279"/>
+ <source>Error occurred attempting to overwrite previous image at: %1.</source>
+ <translation>Помилка під час спроби перезапису попереднього зображення в: %1.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="287"/>
+ <source>Error deleting file</source>
+ <translation>Помилка під час видалення файлу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="288"/>
+ <source>Unable to delete existing file: %1.</source>
+ <translation>Не вдалося видалити наявний файл: %1.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="295"/>
+ <source>Error creating user image directory</source>
+ <translation>Помилка під час створення папки користувацьких зображень</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="296"/>
+ <source>Unable to create directory %1 for storing user images.</source>
+ <translation>Не вийшло створити папку %1 для зберігання зображень користувача.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="301"/>
+ <source>Error copying user image</source>
+ <translation>Помилка під час копіювання зображення користувача</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="302"/>
+ <source>Unable to copy image from %1 to %2</source>
+ <translation>Не вийшло скопіювати зображення з %1 у %2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="311"/>
+ <source>Error resizing user image</source>
+ <translation>Помилка під час зміни розміру зображення користувача</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_profile_manager.cpp" line="312"/>
+ <source>Unable to resize image</source>
+ <translation>Неможливо змінити розмір зображення</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureRingController</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="14"/>
+ <source>Configure Ring Controller</source>
+ <translation>Налаштування контролера Ring</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="26"/>
+ <source>If you want to use this controller configure player 1 as right controller and player 2 as dual joycon before starting the game to allow this controller to be detected properly.</source>
+ <translation>Якщо ви хочете використовувати цей контролер, налаштуйте гравця 1 як правий контролер, а гравця 2 як подвійний Joy-Соп перед початком гри, щоб цей контролер був виявлений правильно.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="52"/>
+ <source>Ring Sensor Parameters</source>
+ <translation>Параметри сенсора Ring</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="84"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="123"/>
+ <source>Pull</source>
+ <translation>Потягнути</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="172"/>
+ <source>Push</source>
+ <translation>Натиснути</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="206"/>
+ <source>Deadzone: 0%</source>
+ <translation>Мертва зона: 0%</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.ui" line="248"/>
+ <source>Restore Defaults</source>
+ <translation>За замовчуванням</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="159"/>
+ <source>Clear</source>
+ <translation>Очистити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="161"/>
+ <source>[not set]</source>
+ <translation>[не задано]</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="163"/>
+ <source>Invert axis</source>
+ <translation>Інвертувати осі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="182"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="238"/>
+ <source>Deadzone: %1%</source>
+ <translation>Мертва зона: %1%</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="262"/>
+ <source>[waiting]</source>
+ <translation>[очікування]</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureSystem</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="17"/>
+ <source>System</source>
+ <translation>Система</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="25"/>
+ <source>System Settings</source>
+ <translation>Налаштування системи</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="33"/>
+ <source>Region:</source>
+ <translation>Регіон:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="41"/>
+ <source>Auto</source>
+ <translation>Авто</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="46"/>
+ <source>Default</source>
+ <translation>За замовчуванням</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="51"/>
+ <source>CET</source>
+ <translation>CET</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="56"/>
+ <source>CST6CDT</source>
+ <translation>CST6CDT</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="61"/>
+ <source>Cuba</source>
+ <translation>Куба</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="66"/>
+ <source>EET</source>
+ <translation>EET</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="71"/>
+ <source>Egypt</source>
+ <translation>Єгипет</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="76"/>
+ <source>Eire</source>
+ <translation>Ейре</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="81"/>
+ <source>EST</source>
+ <translation>EST</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="86"/>
+ <source>EST5EDT</source>
+ <translation>EST5EDT</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="91"/>
+ <source>GB</source>
+ <translation>GB</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="96"/>
+ <source>GB-Eire</source>
+ <translation>GB-Ейре</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="101"/>
+ <source>GMT</source>
+ <translation>GMT</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="106"/>
+ <source>GMT+0</source>
+ <translation>GMT+0</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="111"/>
+ <source>GMT-0</source>
+ <translation>GMT-0</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="116"/>
+ <source>GMT0</source>
+ <translation>GMT0</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="121"/>
+ <source>Greenwich</source>
+ <translation>Гринвіч</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="126"/>
+ <source>Hongkong</source>
+ <translation>Гонконг</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="131"/>
+ <source>HST</source>
+ <translation>HST</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="136"/>
+ <source>Iceland</source>
+ <translation>Ісландія</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="141"/>
+ <source>Iran</source>
+ <translation>Іран</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="146"/>
+ <source>Israel</source>
+ <translation>Ізраїль</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="151"/>
+ <source>Jamaica</source>
+ <translation>Ямайка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="156"/>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="275"/>
+ <source>Japan</source>
+ <translation>Японія</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="161"/>
+ <source>Kwajalein</source>
+ <translation>Кваджалейн</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="166"/>
+ <source>Libya</source>
+ <translation>Лівія</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="171"/>
+ <source>MET</source>
+ <translation>MET</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="176"/>
+ <source>MST</source>
+ <translation>MST</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="181"/>
+ <source>MST7MDT</source>
+ <translation>MST7MDT</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="186"/>
+ <source>Navajo</source>
+ <translation>Навахо</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="191"/>
+ <source>NZ</source>
+ <translation>NZ</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="196"/>
+ <source>NZ-CHAT</source>
+ <translation>NZ-CHAT</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="201"/>
+ <source>Poland</source>
+ <translation>Польща</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="206"/>
+ <source>Portugal</source>
+ <translation>Португалія</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="211"/>
+ <source>PRC</source>
+ <translation>PRC</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="216"/>
+ <source>PST8PDT</source>
+ <translation>PST8PDT</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="221"/>
+ <source>ROC</source>
+ <translation>ROC</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="226"/>
+ <source>ROK</source>
+ <translation>ROK</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="231"/>
+ <source>Singapore</source>
+ <translation>Сінгапур</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="236"/>
+ <source>Turkey</source>
+ <translation>Туреччина</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="241"/>
+ <source>UCT</source>
+ <translation>UCT</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="246"/>
+ <source>Universal</source>
+ <translation>Універсальний</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="251"/>
+ <source>UTC</source>
+ <translation>UTC</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="256"/>
+ <source>W-SU</source>
+ <translation>W-SU</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="261"/>
+ <source>WET</source>
+ <translation>WET</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="266"/>
+ <source>Zulu</source>
+ <translation>Зулуси</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="280"/>
+ <source>USA</source>
+ <translation>США</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="285"/>
+ <source>Europe</source>
+ <translation>Європа</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="290"/>
+ <source>Australia</source>
+ <translation>Австралія</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="295"/>
+ <source>China</source>
+ <translation>Китай</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="300"/>
+ <source>Korea</source>
+ <translation>Корея</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="305"/>
+ <source>Taiwan</source>
+ <translation>Тайвань</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="313"/>
+ <source>Time Zone:</source>
+ <translation>Часовий пояс:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="320"/>
+ <source>Note: this can be overridden when region setting is auto-select</source>
+ <translation>Примітка: може бути перезаписано якщо регіон вибирається автоматично</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="324"/>
+ <source>Japanese (日本語)</source>
+ <translation>Японська (日本語)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="329"/>
+ <source>English</source>
+ <translation>Англійська (English)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="334"/>
+ <source>French (français)</source>
+ <translation>Французька (français)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="339"/>
+ <source>German (Deutsch)</source>
+ <translation>Німецька (Deutsch)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="344"/>
+ <source>Italian (italiano)</source>
+ <translation>Італійська (italiano)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="349"/>
+ <source>Spanish (español)</source>
+ <translation>Іспанська (español)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="354"/>
+ <source>Chinese</source>
+ <translation>Китайська</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="359"/>
+ <source>Korean (한국어)</source>
+ <translation>Корейська (한국어)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="364"/>
+ <source>Dutch (Nederlands)</source>
+ <translation>Голландська (Nederlands)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="369"/>
+ <source>Portuguese (português)</source>
+ <translation>Португальська (português)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="374"/>
+ <source>Russian (Русский)</source>
+ <translation>Російська (Русский)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="379"/>
+ <source>Taiwanese</source>
+ <translation>Тайванська</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="384"/>
+ <source>British English</source>
+ <translation>Британська Англійська</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="389"/>
+ <source>Canadian French</source>
+ <translation>Канадська Французька</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="394"/>
+ <source>Latin American Spanish</source>
+ <translation>Латиноамериканська Іспанська</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="399"/>
+ <source>Simplified Chinese</source>
+ <translation>Спрощена Китайська</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="404"/>
+ <source>Traditional Chinese (正體中文)</source>
+ <translation>Традиційна Китайська (正體中文)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="409"/>
+ <source>Brazilian Portuguese (português do Brasil)</source>
+ <translation>Бразильська Португальська (português do Brasil)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="417"/>
+ <source>Custom RTC</source>
+ <translation>Користувацький RTC</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="424"/>
+ <source>Language</source>
+ <translation>Мова</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="431"/>
+ <source>RNG Seed</source>
+ <translation>Сід RNG</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="439"/>
+ <source>Mono</source>
+ <translation>Моно</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="444"/>
+ <source>Stereo</source>
+ <translation>Стерео</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="449"/>
+ <source>Surround</source>
+ <translation>Об&apos;ємний звук</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="457"/>
+ <source>Console ID:</source>
+ <translation>Ідентифікатор консолі:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="464"/>
+ <source>Sound output mode</source>
+ <translation>Режим виводу звуку</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="512"/>
+ <source>Regenerate</source>
+ <translation>Перегенерувати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.ui" line="537"/>
+ <source>System settings are available only when game is not running.</source>
+ <translation>Налаштування системи доступні тільки тоді, коли гру не запущено.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.cpp" line="161"/>
+ <source>This will replace your current virtual Switch with a new one. Your current virtual Switch will not be recoverable. This might have unexpected effects in games. This might fail, if you use an outdated config savegame. Continue?</source>
+ <translation>Це замінить ваш поточний віртуальний Switch новим. Ваш поточний віртуальний Switch буде безповоротно втрачено. Це може мати несподівані наслідки в іграх. Може не спрацювати, якщо ви використовуєте застарілу конфігурацію збережених ігор. Продовжити?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.cpp" line="165"/>
+ <source>Warning</source>
+ <translation>Увага</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_system.cpp" line="173"/>
+ <source>Console ID: 0x%1</source>
+ <translation>Ідентифікатор консолі: 0x%1</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureTas</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="11"/>
+ <source>TAS</source>
+ <translation>TAS</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="17"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reads controller input from scripts in the same format as TAS-nx scripts.&lt;br/&gt;For a more detailed explanation, please consult the &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;help page&lt;/span&gt;&lt;/a&gt; on the yuzu website.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Зчитує вхідні дані контролера зі скриптів у тому ж форматі, що і скрипти TAS-nx.&lt;br/&gt;Для більш детального пояснення зверніться до &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;сторінки допомоги&lt;/span&gt;&lt;/a&gt; на сайті yuzu.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
+ <source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
+ <translation>Щоб перевірити, які гарячі клавіші керують відтворенням/записом, зверніться до налаштувань гарячих клавіш (Налаштування - Загальні -&gt; Гарячі клавіші).</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
+ <source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
+ <translation>ПОПЕРЕДЖЕННЯ: Це експериментальна функція.&lt;br/&gt;Вона не буде ідеально відтворювати кадри сценаріїв за поточного недосконалого методу синхронізації.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
+ <source>Settings</source>
+ <translation>Налаштування</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
+ <source>Enable TAS features</source>
+ <translation>Увімкнути функції TAS</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
+ <source>Loop script</source>
+ <translation>Зациклити скрипт</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
+ <source>Pause execution during loads</source>
+ <translation>Призупинити виконання під час завантаження</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
+ <source>Script Directory</source>
+ <translation>Папка для скриптів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
+ <source>Path</source>
+ <translation>Шлях</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
+ <source>...</source>
+ <translation>...</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureTasDialog</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_tas.cpp" line="19"/>
+ <source>TAS Configuration</source>
+ <translation>Налаштування TAS</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_tas.cpp" line="50"/>
+ <source>Select TAS Load Directory...</source>
+ <translation>Обрати папку завантаження TAS...</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureTouchFromButton</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.ui" line="14"/>
+ <source>Configure Touchscreen Mappings</source>
+ <translation>Налаштування відображення сенсорного екрана</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.ui" line="22"/>
+ <source>Mapping:</source>
+ <translation>Прив&apos;язки:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.ui" line="48"/>
+ <source>New</source>
+ <translation>Новий</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.ui" line="61"/>
+ <source>Delete</source>
+ <translation>Видалити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.ui" line="74"/>
+ <source>Rename</source>
+ <translation>Перейменувати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.ui" line="92"/>
+ <source>Click the bottom area to add a point, then press a button to bind.
+Drag points to change position, or double-click table cells to edit values.</source>
+ <translation>Натисніть на нижній області, щоб додати точку, після чого натисніть кнопку для прив&apos;язки.
+Перетягніть точки, щоб змінити позицію, або натисніть двічі на комірки таблиці для зміни значень.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.ui" line="116"/>
+ <source>Delete Point</source>
+ <translation>Видалити точку</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="78"/>
+ <source>Button</source>
+ <translation>Кнопка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="78"/>
+ <source>X</source>
+ <comment>X axis</comment>
+ <translation>X</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="78"/>
+ <source>Y</source>
+ <comment>Y axis</comment>
+ <translation>Y</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="195"/>
+ <source>New Profile</source>
+ <translation>Новий профіль</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="195"/>
+ <source>Enter the name for the new profile.</source>
+ <translation>Введіть ім&apos;я вашого нового профілю.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="206"/>
+ <source>Delete Profile</source>
+ <translation>Видалити профіль</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="206"/>
+ <source>Delete profile %1?</source>
+ <translation>Видалити профіль %1?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="219"/>
+ <source>Rename Profile</source>
+ <translation>Перейменувати профіль</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="219"/>
+ <source>New name:</source>
+ <translation>Нова назва:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="231"/>
+ <source>[press key]</source>
+ <translation>[натисніть клавішу]</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureTouchscreenAdvanced</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="14"/>
+ <source>Configure Touchscreen</source>
+ <translation>Налаштування сенсорного екрана</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="26"/>
+ <source>Warning: The settings in this page affect the inner workings of yuzu&apos;s emulated touchscreen. Changing them may result in undesirable behavior, such as the touchscreen partially or not working. You should only use this page if you know what you are doing.</source>
+ <translation>Увага: Налаштування на цій сторінці впливають на внутрішню роботу емульованого сенсорного екрана yuzu. Їх зміна може призвести до небажаної поведінки, як часткова або повна непрацездатність сенсорного екрана. Використовуйте цю сторінку лише якщо ви знаєте, що робите.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="52"/>
+ <source>Touch Parameters</source>
+ <translation>Параметри сенсора</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="71"/>
+ <source>Touch Diameter Y</source>
+ <translation>Діаметр сенсора Y</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="91"/>
+ <source>Touch Diameter X</source>
+ <translation>Діаметр сенсора X</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="98"/>
+ <source>Rotational Angle</source>
+ <translation>Кут повороту</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touchscreen_advanced.ui" line="132"/>
+ <source>Restore Defaults</source>
+ <translation>За замовчуванням</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureUI</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="20"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="28"/>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="40"/>
+ <source>None</source>
+ <translation>Нічого</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="21"/>
+ <source>Small (32x32)</source>
+ <translation>Маленький (32х32)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="22"/>
+ <source>Standard (64x64)</source>
+ <translation>Стандартний (64х64)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="23"/>
+ <source>Large (128x128)</source>
+ <translation>Великий (128х128)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="24"/>
+ <source>Full Size (256x256)</source>
+ <translation>Повнорозмірний (256х256)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="29"/>
+ <source>Small (24x24)</source>
+ <translation>Маленький (24х24)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="30"/>
+ <source>Standard (48x48)</source>
+ <translation>Стандартний (48х48)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="31"/>
+ <source>Large (72x72)</source>
+ <translation>Великий (72х72)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="36"/>
+ <source>Filename</source>
+ <translation>Ім&apos;я файлу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="37"/>
+ <source>Filetype</source>
+ <translation>Тип файлу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="38"/>
+ <source>Title ID</source>
+ <translation>Ідентифікатор гри</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="39"/>
+ <source>Title Name</source>
+ <translation>Назва гри</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureUi</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="17"/>
+ <source>UI</source>
+ <translation>Інтерфейс</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="23"/>
+ <source>General</source>
+ <translation>Загальні</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="31"/>
+ <source>Note: Changing language will apply your configuration.</source>
+ <translation>Примітка: Зміна мови призведе до застосування налаштувань.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="43"/>
+ <source>Interface language:</source>
+ <translation>Мова інтерфейсу:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="57"/>
+ <source>Theme:</source>
+ <translation>Тема:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="74"/>
+ <source>Game List</source>
+ <translation>Список ігор</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="82"/>
+ <source>Show Compatibility List</source>
+ <translation>Показати список сумісності</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="89"/>
+ <source>Show Add-Ons Column</source>
+ <translation>Показувати стовпець доповнень</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="98"/>
+ <source>Game Icon Size:</source>
+ <translation>Розмір іконки гри:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="112"/>
+ <source>Folder Icon Size:</source>
+ <translation>Розмір іконки папки:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="126"/>
+ <source>Row 1 Text:</source>
+ <translation>Текст 1-го рядку:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="140"/>
+ <source>Row 2 Text:</source>
+ <translation>Текст 2-го рядку:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="157"/>
+ <source>Screenshots</source>
+ <translation>Знімки екрану</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="165"/>
+ <source>Ask Where To Save Screenshots (Windows Only)</source>
+ <translation>Запитувати куди зберігати знімки екрану (Тільки для Windows)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="174"/>
+ <source>Screenshots Path: </source>
+ <translation>Папка для знімків екрану:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.ui" line="184"/>
+ <source>...</source>
+ <translation>...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="94"/>
+ <source>Select Screenshots Path...</source>
+ <translation>Виберіть папку для знімків екрану...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ui.cpp" line="219"/>
+ <source>&lt;System&gt;</source>
+ <translation>&lt;System&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureVibration</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="14"/>
+ <source>Configure Vibration</source>
+ <translation>Налаштування вібрації</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="23"/>
+ <source>Press any controller button to vibrate the controller.</source>
+ <translation>Натисніть будь-яку кнопку контролера, щоб викликати вібрацію.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="30"/>
+ <source>Vibration</source>
+ <translation>Вібрація</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="63"/>
+ <source>Player 1</source>
+ <translation>Гравець 1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="96"/>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="200"/>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="252"/>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="322"/>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="374"/>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="426"/>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="478"/>
+ <source>%</source>
+ <translation>%</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="115"/>
+ <source>Player 2</source>
+ <translation>Гравець 2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="167"/>
+ <source>Player 3</source>
+ <translation>Гравець 3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="219"/>
+ <source>Player 4</source>
+ <translation>Гравець 4</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="289"/>
+ <source>Player 5</source>
+ <translation>Гравець 5</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="341"/>
+ <source>Player 6</source>
+ <translation>Гравець 6</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="393"/>
+ <source>Player 7</source>
+ <translation>Гравець 7</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="445"/>
+ <source>Player 8</source>
+ <translation>Гравець 8</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="503"/>
+ <source>Settings</source>
+ <translation>Налаштування</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_vibration.ui" line="509"/>
+ <source>Enable Accurate Vibration</source>
+ <translation>Увімкнути точну вібрацію</translation>
+ </message>
+</context>
+<context>
+ <name>ConfigureWeb</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="14"/>
+ <source>Form</source>
+ <translation>Форма</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="17"/>
+ <source>Web</source>
+ <translation>Мережа</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="25"/>
+ <source>yuzu Web Service</source>
+ <translation>Веб-сервіс yuzu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="31"/>
+ <source>By providing your username and token, you agree to allow yuzu to collect additional usage data, which may include user identifying information.</source>
+ <translation>Надаючи своє ім&apos;я користувача і токен, ви погоджуєтеся дозволити yuzu збирати додаткові дані про використання, які можуть включати інформацію, що ідентифікує користувача.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
+ <source>Verify</source>
+ <translation>Підтвердити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="56"/>
+ <source>Sign up</source>
+ <translation>Реєстрація</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="66"/>
+ <source>Token: </source>
+ <translation>Токен:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="76"/>
+ <source>Username: </source>
+ <translation>Ім&apos;я користувача:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="93"/>
+ <source>What is my token?</source>
+ <translation>Що таке токен і де його знайти?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="118"/>
+ <source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
+ <translation>Налаштування веб-служби можуть бути змінені тільки в тому випадку, коли не хоститься публічна кімната.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="128"/>
+ <source>Telemetry</source>
+ <translation>Телеметрія</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="134"/>
+ <source>Share anonymous usage data with the yuzu team</source>
+ <translation>Ділитися анонімною інформацією про використання з командою yuzu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="141"/>
+ <source>Learn more</source>
+ <translation>Дізнатися більше</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="150"/>
+ <source>Telemetry ID:</source>
+ <translation>Ідентифікатор телеметрії:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="166"/>
+ <source>Regenerate</source>
+ <translation>Перегенерувати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="180"/>
+ <source>Discord Presence</source>
+ <translation>Discord Presence</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.ui" line="186"/>
+ <source>Show Current Game in your Discord Status</source>
+ <translation>Показувати поточну гру у вашому статусі Discord</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="68"/>
+ <source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Learn more&lt;/span&gt;&lt;/a&gt;</source>
+ <translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Дізнатися більше&lt;/span&gt;&lt;/a&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="72"/>
+ <source>&lt;a href=&apos;https://profile.yuzu-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Sign up&lt;/span&gt;&lt;/a&gt;</source>
+ <translation>&lt;a href=&apos;https://profile.yuzu-emu.org/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Реєстрація&lt;/span&gt;&lt;/a&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="76"/>
+ <source>&lt;a href=&apos;https://yuzu-emu.org/wiki/yuzu-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;What is my token?&lt;/span&gt;&lt;/a&gt;</source>
+ <translation>&lt;a href=&apos;https://yuzu-emu.org/wiki/yuzu-web-service/&apos;&gt;&lt;span style=&quot;text-decoration: underline; color:#039be5;&quot;&gt;Що таке токен і де його знайти?&lt;/span&gt;&lt;/a&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="125"/>
+ <source>Telemetry ID: 0x%1</source>
+ <translation>Ідентифікатор телеметрії: 0x%1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
+ <source>Unspecified</source>
+ <translation>Відсутній</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="117"/>
+ <source>Token not verified</source>
+ <translation>Токен не підтверджено</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="118"/>
+ <source>Token was not verified. The change to your token has not been saved.</source>
+ <translation>Токен не було підтверджено. Зміну вашого токена не було збережено.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation>Не підтверджено, будь ласка, натисніть кнопку Підтвердити, перш ніж зберігати конфігурацію.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
+ <source>Verifying...</source>
+ <translation>Підтверждення...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation>Підтверджено</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
+ <source>Verification failed</source>
+ <comment>Tooltip</comment>
+ <translation>Підтверждення не було успішним</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Підтверждення не було успішним</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
+ <source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
+ <translation>Підтверждення не було успішним. Переконайтеся, що ви правильно ввели свій токен і що ваше інтернет-з&apos;єднання працює.</translation>
+ </message>
+</context>
+<context>
+ <name>ControllerDialog</name>
+ <message>
+ <location filename="../../src/yuzu/debugger/controller.cpp" line="20"/>
+ <source>Controller P1</source>
+ <translation>Контролер P1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/controller.cpp" line="59"/>
+ <source>&amp;Controller P1</source>
+ <translation>[&amp;C] Контролер P1</translation>
+ </message>
+</context>
+<context>
+ <name>DirectConnect</name>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="14"/>
+ <source>Direct Connect</source>
+ <translation>Пряме підключення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="33"/>
+ <source>IP Address</source>
+ <translation>IP-адреса</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="56"/>
+ <source>IP</source>
+ <translation>IP</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="63"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;IPv4 address of the host&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;IPv4 адреса хоста&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="73"/>
+ <source>Port</source>
+ <translation>Порт</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="80"/>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Port number the host is listening on&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Номер порту, який прослуховується хостом&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="100"/>
+ <source>Nickname</source>
+ <translation>Псевдонім</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="114"/>
+ <source>Password</source>
+ <translation>Пароль</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.ui" line="156"/>
+ <source>Connect</source>
+ <translation>Підключитися</translation>
+ </message>
+</context>
+<context>
+ <name>DirectConnectWindow</name>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="127"/>
+ <source>Connecting</source>
+ <translation>Підключення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="132"/>
+ <source>Connect</source>
+ <translation>Підключитися</translation>
+ </message>
+</context>
+<context>
+ <name>GMainWindow</name>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="188"/>
+ <source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
+ <translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Анонімні дані збираються для того,&lt;/a&gt; щоб допомогти поліпшити роботу yuzu. &lt;br/&gt;&lt;br/&gt;Хотіли б ви ділитися даними про використання з нами?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="191"/>
+ <source>Telemetry</source>
+ <translation>Телеметрія</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="405"/>
+ <source>Broken Vulkan Installation Detected</source>
+ <translation>Виявлено пошкоджену інсталяцію Vulkan</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="406"/>
+ <source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
+ <translation>Не вдалося виконати ініціалізацію Vulkan під час завантаження.&lt;br&gt;&lt;br&gt;Натисніть &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;тут для отримання інструкцій щодо усунення проблеми&lt;/a&gt;.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="734"/>
+ <source>Loading Web Applet...</source>
+ <translation>Завантаження веб-аплета...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="781"/>
+ <location filename="../../src/yuzu/main.cpp" line="784"/>
+ <source>Disable Web Applet</source>
+ <translation>Вимкнути веб-аплет</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="785"/>
+ <source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
+(This can be re-enabled in the Debug settings.)</source>
+ <translation>Вимкнення веб-апплета може призвести до несподіваної поведінки, і його слід вимикати лише заради Super Mario 3D All-Stars. Ви впевнені, що хочете вимкнути веб-апплет?
+(Його можна знову ввімкнути в налаштуваннях налагодження.)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="892"/>
+ <source>The amount of shaders currently being built</source>
+ <translation>Кількість створюваних шейдерів на цей момент</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="894"/>
+ <source>The current selected resolution scaling multiplier.</source>
+ <translation>Поточний обраний множник масштабування роздільної здатності.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="897"/>
+ <source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
+ <translation>Поточна швидкість емуляції. Значення вище або нижче 100% вказують на те, що емуляція йде швидше або повільніше, ніж на Switch.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="900"/>
+ <source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
+ <translation>Кількість кадрів на секунду в цей момент. Значення буде змінюватися між іграми та сценами.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="904"/>
+ <source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
+ <translation>Час, який потрібен для емуляції 1 кадру Switch, не беручи до уваги обмеження FPS або вертикальну синхронізацію. Для емуляції в повній швидкості значення має бути не більше 16,67 мс.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="983"/>
+ <source>VULKAN</source>
+ <translation>VULKAN</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="983"/>
+ <source>OPENGL</source>
+ <translation>OPENGL</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1045"/>
+ <source>&amp;Clear Recent Files</source>
+ <translation>[&amp;C] Очистити нещодавні файли</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1353"/>
+ <source>&amp;Continue</source>
+ <translation>[&amp;C] Продовжити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1355"/>
+ <source>&amp;Pause</source>
+ <translation>[&amp;P] Пауза</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1435"/>
+ <source>yuzu is running a game</source>
+ <extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
+ <translation>В yuzu запущено гру</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1566"/>
+ <source>Warning Outdated Game Format</source>
+ <translation>Попередження застарілий формат гри</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
+ <source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
+ <translation>Для цієї гри ви використовуєте розархівований формат ROM&apos;а, який є застарілим і був замінений іншими, такими як NCA, NAX, XCI або NSP. У розархівованих каталогах ROM&apos;а відсутні іконки, метадані та підтримка оновлень. &lt;br&gt;&lt;br&gt;Для отримання інформації про різні формати Switch, підтримувані yuzu, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;перегляньте нашу вікі&lt;/a&gt;. Це повідомлення більше не буде відображатися.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1579"/>
+ <location filename="../../src/yuzu/main.cpp" line="1613"/>
+ <source>Error while loading ROM!</source>
+ <translation>Помилка під час завантаження ROM!</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <source>The ROM format is not supported.</source>
+ <translation>Формат ROM&apos;а не підтримується.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1584"/>
+ <source>An error occurred initializing the video core.</source>
+ <translation>Сталася помилка під час ініціалізації відеоядра.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1585"/>
+ <source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
+ <translation>yuzu зіткнувся з помилкою під час запуску відеоядра. Зазвичай це спричинено застарілими драйверами ГП, включно з інтегрованими. Перевірте журнал для отримання більш детальної інформації. Додаткову інформацію про доступ до журналу дивіться на наступній сторінці: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;Як завантажити файл журналу&lt;/a&gt;. </translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1600"/>
+ <source>Error while loading ROM! %1</source>
+ <comment>%1 signifies a numeric error code.</comment>
+ <translation>Помилка під час завантаження ROM&apos;а! %1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1603"/>
+ <source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
+ <comment>%1 signifies an error string.</comment>
+ <translation>%1&lt;br&gt;Будь ласка, дотримуйтесь &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;короткого керівництва користувача yuzu&lt;/a&gt; щоб пере-дампити ваші файли&lt;br&gt;Ви можете звернутися до вікі yuzu&lt;/a&gt; або Discord yuzu&lt;/a&gt; для допомоги</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1614"/>
+ <source>An unknown error occurred. Please see the log for more details.</source>
+ <translation>Сталася невідома помилка. Будь ласка, перевірте журнал для подробиць.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1746"/>
+ <source>(64-bit)</source>
+ <translation>(64-бітний)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1746"/>
+ <source>(32-bit)</source>
+ <translation>(32-бітний)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1747"/>
+ <source>%1 %2</source>
+ <comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
+ <translation>%1 %2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1897"/>
+ <source>Save Data</source>
+ <translation>Збереження</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1947"/>
+ <source>Mod Data</source>
+ <translation>Дані модів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1959"/>
+ <source>Error Opening %1 Folder</source>
+ <translation>Помилка під час відкриття папки %1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1960"/>
+ <location filename="../../src/yuzu/main.cpp" line="2366"/>
+ <source>Folder does not exist!</source>
+ <translation>Папка не існує!</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1972"/>
+ <source>Error Opening Transferable Shader Cache</source>
+ <translation>Помилка під час відкриття переносного кешу шейдерів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="1973"/>
+ <source>Failed to create the shader cache directory for this title.</source>
+ <translation>Не вдалося створити папку кешу шейдерів для цієї гри.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2025"/>
+ <source>Contents</source>
+ <translation>Зміст</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2027"/>
+ <source>Update</source>
+ <translation>Оновлення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2029"/>
+ <source>DLC</source>
+ <translation>DLC</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2036"/>
+ <source>Remove Entry</source>
+ <translation>Видалити запис</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2036"/>
+ <source>Remove Installed Game %1?</source>
+ <translation>Видалити встановлену гру %1?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2082"/>
+ <location filename="../../src/yuzu/main.cpp" line="2113"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
+ <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2215"/>
+ <source>Successfully Removed</source>
+ <translation>Успішно видалено</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
+ <source>Successfully removed the installed base game.</source>
+ <translation>Встановлену гру успішно видалено.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2070"/>
+ <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2108"/>
+ <source>Error Removing %1</source>
+ <translation>Помилка під час видалення %1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2071"/>
+ <source>The base game is not installed in the NAND and cannot be removed.</source>
+ <translation>Гру не встановлено в NAND і не може буде видалено.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2083"/>
+ <source>Successfully removed the installed update.</source>
+ <translation>Встановлене оновлення успішно видалено.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <source>There is no update installed for this title.</source>
+ <translation>Для цієї гри не було встановлено оновлення.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
+ <source>There are no DLC installed for this title.</source>
+ <translation>Для цієї гри не було встановлено DLC.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2114"/>
+ <source>Successfully removed %1 installed DLC.</source>
+ <translation>Встановлений DLC %1 було успішно видалено</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2122"/>
+ <source>Delete OpenGL Transferable Shader Cache?</source>
+ <translation>Видалити переносний кеш шейдерів OpenGL?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2124"/>
+ <source>Delete Vulkan Transferable Shader Cache?</source>
+ <translation>Видалити переносний кеш шейдерів Vulakn?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2126"/>
+ <source>Delete All Transferable Shader Caches?</source>
+ <translation>Видалити весь переносний кеш шейдерів?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2128"/>
+ <source>Remove Custom Game Configuration?</source>
+ <translation>Видалити користувацьке налаштування гри?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2134"/>
+ <source>Remove File</source>
+ <translation>Видалити файл</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
+ <source>Error Removing Transferable Shader Cache</source>
+ <translation>Помилка під час видалення переносного кешу шейдерів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2188"/>
+ <source>A shader cache for this title does not exist.</source>
+ <translation>Кеш шейдерів для цієї гри не існує.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2175"/>
+ <source>Successfully removed the transferable shader cache.</source>
+ <translation>Переносний кеш шейдерів успішно видалено.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2178"/>
+ <source>Failed to remove the transferable shader cache.</source>
+ <translation>Не вдалося видалити переносний кеш шейдерів.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <source>Error Removing Transferable Shader Caches</source>
+ <translation>Помилка під час видалення переносного кешу шейдерів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <source>Successfully removed the transferable shader caches.</source>
+ <translation>Переносний кеш шейдерів успішно видалено.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <source>Failed to remove the transferable shader cache directory.</source>
+ <translation>Помилка під час видалення папки переносного кешу шейдерів.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2209"/>
+ <location filename="../../src/yuzu/main.cpp" line="2218"/>
+ <source>Error Removing Custom Configuration</source>
+ <translation>Помилка під час видалення користувацького налаштування</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2210"/>
+ <source>A custom configuration for this title does not exist.</source>
+ <translation>Користувацьких налаштувань для цієї гри не існує.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2216"/>
+ <source>Successfully removed the custom game configuration.</source>
+ <translation>Користувацьке налаштування гри успішно видалено.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2219"/>
+ <source>Failed to remove the custom game configuration.</source>
+ <translation>Не вдалося видалити користувацьке налаштування гри.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2226"/>
+ <location filename="../../src/yuzu/main.cpp" line="2305"/>
+ <source>RomFS Extraction Failed!</source>
+ <translation>Не вдалося вилучити RomFS!</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2227"/>
+ <source>There was an error copying the RomFS files or the user cancelled the operation.</source>
+ <translation>Сталася помилка під час копіювання файлів RomFS або користувач скасував операцію.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2285"/>
+ <source>Full</source>
+ <translation>Повний</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2285"/>
+ <source>Skeleton</source>
+ <translation>Скелет</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
+ <source>Select RomFS Dump Mode</source>
+ <translation>Виберіть режим дампа RomFS</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2288"/>
+ <source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
+ <translation>Будь ласка, виберіть, як ви хочете виконати дамп RomFS &lt;br&gt;Повний скопіює всі файли в нову папку, тоді як &lt;br&gt;скелет створить лише структуру папок.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2306"/>
+ <source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
+ <translation>В %1 недостатньо вільного місця для вилучення RomFS. Будь ласка, звільніть місце або виберіть іншу папку для дампа в Емуляція &gt; Налаштування &gt; Система &gt; Файлова система &gt; Корінь дампа</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2313"/>
+ <source>Extracting RomFS...</source>
+ <translation>Вилучення RomFS...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2313"/>
+ <location filename="../../src/yuzu/main.cpp" line="2499"/>
+ <source>Cancel</source>
+ <translation>Скасувати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2320"/>
+ <source>RomFS Extraction Succeeded!</source>
+ <translation>Вилучення RomFS пройшло успішно!</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2321"/>
+ <source>The operation completed successfully.</source>
+ <translation>Операція завершилася успішно.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2365"/>
+ <source>Error Opening %1</source>
+ <translation>Помилка відкриття %1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2374"/>
+ <source>Select Directory</source>
+ <translation>Обрати папку</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2401"/>
+ <source>Properties</source>
+ <translation>Властивості</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2402"/>
+ <source>The game properties could not be loaded.</source>
+ <translation>Не вдалося завантажити властивості гри.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2419"/>
+ <source>Switch Executable (%1);;All Files (*.*)</source>
+ <comment>%1 is an identifier for the Switch executable file extensions.</comment>
+ <translation>Виконуваний файл Switch (%1);;Усі файли (*.*)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2423"/>
+ <source>Load File</source>
+ <translation>Завантажити файл</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2436"/>
+ <source>Open Extracted ROM Directory</source>
+ <translation>Відкрити папку вилученого ROM&apos;а</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2447"/>
+ <source>Invalid Directory Selected</source>
+ <translation>Вибрано неприпустиму папку</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2448"/>
+ <source>The directory you have selected does not contain a &apos;main&apos; file.</source>
+ <translation>Папка, яку ви вибрали, не містить файлу &apos;main&apos;.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2458"/>
+ <source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
+ <translation>Встановлюваний файл Switch (*.nca, *.nsp, *.xci);;Архів контенту Nintendo (*.nca);;Пакет подачі Nintendo (*.nsp);;Образ картриджа NX (*.xci)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2463"/>
+ <source>Install Files</source>
+ <translation>Встановити файли</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../src/yuzu/main.cpp" line="2507"/>
+ <source>%n file(s) remaining</source>
+ <translation><numerusform>Залишився %n файл</numerusform><numerusform>Залишилося %n файл(ів)</numerusform><numerusform>Залишилося %n файл(ів)</numerusform><numerusform>Залишилося %n файл(ів)</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2509"/>
+ <source>Installing file &quot;%1&quot;...</source>
+ <translation>Встановлення файлу &quot;%1&quot;...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2555"/>
+ <location filename="../../src/yuzu/main.cpp" line="2569"/>
+ <source>Install Results</source>
+ <translation>Результати встановлення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2556"/>
+ <source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
+Please, only use this feature to install updates and DLC.</source>
+ <translation>Щоб уникнути можливих конфліктів, ми не рекомендуємо користувачам встановлювати ігри в NAND.
+Будь ласка, використовуйте цю функцію тільки для встановлення оновлень і завантажуваного контенту.</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../src/yuzu/main.cpp" line="2562"/>
+ <source>%n file(s) were newly installed
+</source>
+ <translation><numerusform>%n файл було нещодавно встановлено
+</numerusform><numerusform>%n файл(ів) було нещодавно встановлено
+</numerusform><numerusform>%n файл(ів) було нещодавно встановлено
+</numerusform><numerusform>%n файл(ів) було нещодавно встановлено
+</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../src/yuzu/main.cpp" line="2565"/>
+ <source>%n file(s) were overwritten
+</source>
+ <translation><numerusform>%n файл було перезаписано
+</numerusform><numerusform>%n файл(ів) було перезаписано
+</numerusform><numerusform>%n файл(ів) було перезаписано
+</numerusform><numerusform>%n файл(ів) було перезаписано
+</numerusform></translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../src/yuzu/main.cpp" line="2567"/>
+ <source>%n file(s) failed to install
+</source>
+ <translation><numerusform>%n файл не вдалося встановити
+</numerusform><numerusform>%n файл(ів) не вдалося встановити
+</numerusform><numerusform>%n файл(ів) не вдалося встановити
+</numerusform><numerusform>%n файл(ів) не вдалося встановити
+</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
+ <source>System Application</source>
+ <translation>Системний додаток</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2669"/>
+ <source>System Archive</source>
+ <translation>Системний архів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2670"/>
+ <source>System Application Update</source>
+ <translation>Оновлення системного додатку</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2671"/>
+ <source>Firmware Package (Type A)</source>
+ <translation>Пакет прошивки (Тип А)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2672"/>
+ <source>Firmware Package (Type B)</source>
+ <translation>Пакет прошивки (Тип Б)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2673"/>
+ <source>Game</source>
+ <translation>Гра</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2674"/>
+ <source>Game Update</source>
+ <translation>Оновлення гри</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2675"/>
+ <source>Game DLC</source>
+ <translation>DLC до гри</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2676"/>
+ <source>Delta Title</source>
+ <translation>Дельта-титул</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2679"/>
+ <source>Select NCA Install Type...</source>
+ <translation>Виберіть тип установки NCA...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2680"/>
+ <source>Please select the type of title you would like to install this NCA as:
+(In most instances, the default &apos;Game&apos; is fine.)</source>
+ <translation>Будь ласка, виберіть тип додатку, який ви хочете встановити для цього NCA:
+(У більшості випадків, підходить стандартний вибір &quot;Гра&quot;.)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2686"/>
+ <source>Failed to Install</source>
+ <translation>Помилка встановлення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2687"/>
+ <source>The title type you selected for the NCA is invalid.</source>
+ <translation>Тип додатку, який ви вибрали для NCA, недійсний.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2722"/>
+ <source>File not found</source>
+ <translation>Файл не знайдено</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2723"/>
+ <source>File &quot;%1&quot; not found</source>
+ <translation>Файл &quot;%1&quot; не знайдено</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2798"/>
+ <source>OK</source>
+ <translation>ОК</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2812"/>
+ <source>Missing yuzu Account</source>
+ <translation>Відсутній обліковий запис yuzu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2813"/>
+ <source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
+ <translation>Щоб надіслати звіт про сумісність гри, необхідно прив&apos;язати свій обліковий запис yuzu. &lt;br&gt;&lt;br/&gt;Щоб прив&apos;язати свій обліковий запис yuzu, перейдіть у розділ Емуляція &amp;gt; Параметри &amp;gt; Мережа.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2823"/>
+ <source>Error opening URL</source>
+ <translation>Помилка під час відкриття URL</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="2824"/>
+ <source>Unable to open the URL &quot;%1&quot;.</source>
+ <translation>Не вдалося відкрити URL: &quot;%1&quot;.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3120"/>
+ <source>TAS Recording</source>
+ <translation>Запис TAS</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3121"/>
+ <source>Overwrite file of player 1?</source>
+ <translation>Перезаписати файл гравця 1?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3147"/>
+ <source>Invalid config detected</source>
+ <translation>Виявлено неприпустиму конфігурацію</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3148"/>
+ <source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
+ <translation>Портативний контролер не може бути використаний у режимі док-станції. Буде обрано контролер Pro.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3243"/>
+ <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <source>Amiibo</source>
+ <translation>Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3243"/>
+ <location filename="../../src/yuzu/main.cpp" line="3271"/>
+ <source>The current amiibo has been removed</source>
+ <translation>Поточний amiibo було прибрано</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3248"/>
+ <source>Error</source>
+ <translation>Помилка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3248"/>
+ <location filename="../../src/yuzu/main.cpp" line="3283"/>
+ <source>The current game is not looking for amiibos</source>
+ <translation>Поточна гра не шукає amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3254"/>
+ <source>Amiibo File (%1);; All Files (*.*)</source>
+ <translation>Файл Amiibo (%1);; Всі Файли (*.*)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3255"/>
+ <source>Load Amiibo</source>
+ <translation>Завантажити Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3267"/>
+ <source>Error loading Amiibo data</source>
+ <translation>Помилка під час завантаження даних Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <source>The selected file is not a valid amiibo</source>
+ <translation>Обраний файл не є допустимим amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3280"/>
+ <source>The selected file is already on use</source>
+ <translation>Обраний файл уже використовується</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3286"/>
+ <source>An unknown error occurred</source>
+ <translation>Виникла невідома помилка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3338"/>
+ <source>Capture Screenshot</source>
+ <translation>Зробити знімок екрану</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3339"/>
+ <source>PNG Image (*.png)</source>
+ <translation>Зображення PNG (*.png)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3405"/>
+ <source>TAS state: Running %1/%2</source>
+ <translation>Стан TAS: Виконується %1/%2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3407"/>
+ <source>TAS state: Recording %1</source>
+ <translation>Стан TAS: Записується %1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3409"/>
+ <source>TAS state: Idle %1/%2</source>
+ <translation>Стан TAS: Простий %1/%2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3411"/>
+ <source>TAS State: Invalid</source>
+ <translation>Стан TAS: Неприпустимий</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
+ <source>&amp;Stop Running</source>
+ <translation>[&amp;S] Зупинка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
+ <source>&amp;Start</source>
+ <translation>[&amp;S] Почати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3426"/>
+ <source>Stop R&amp;ecording</source>
+ <translation>[&amp;E] Закінчити запис</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3426"/>
+ <source>R&amp;ecord</source>
+ <translation>[&amp;E] Запис</translation>
+ </message>
+ <message numerus="yes">
+ <location filename="../../src/yuzu/main.cpp" line="3450"/>
+ <source>Building: %n shader(s)</source>
+ <translation><numerusform>Побудова: %n шейдер</numerusform><numerusform>Побудова: %n шейдер(ів)</numerusform><numerusform>Побудова: %n шейдер(ів)</numerusform><numerusform>Побудова: %n шейдер(ів)</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <source>Scale: %1x</source>
+ <comment>%1 is the resolution scaling factor</comment>
+ <translation>Масштаб: %1x</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3462"/>
+ <source>Speed: %1% / %2%</source>
+ <translation>Швидкість: %1% / %2%</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3466"/>
+ <source>Speed: %1%</source>
+ <translation>Швидкість: %1%</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
+ <source>Game: %1 FPS (Unlocked)</source>
+ <translation>Гра: %1 FPS (Необмежено)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3473"/>
+ <source>Game: %1 FPS</source>
+ <translation>Гра: %1 FPS</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
+ <source>Frame: %1 ms</source>
+ <translation>Кадр: %1 мс</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3486"/>
+ <source>GPU NORMAL</source>
+ <translation>ГП НОРМАЛЬНО</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
+ <source>GPU HIGH</source>
+ <translation>ГП ВИСОКО</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3496"/>
+ <source>GPU EXTREME</source>
+ <translation>ГП ЕКСТРИМ</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3501"/>
+ <source>GPU ERROR</source>
+ <translation>ГП ПОМИЛКА</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3510"/>
+ <source>DOCKED</source>
+ <translation>В ДОК-СТАНЦІЇ</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3510"/>
+ <source>HANDHELD</source>
+ <translation>ПОРТАТИВНИЙ</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <source>NEAREST</source>
+ <translation>НАЙБЛИЖЧІЙ</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <source>BILINEAR</source>
+ <translation>БІЛІНІЙНИЙ</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <source>BICUBIC</source>
+ <translation>БІКУБІЧНИЙ</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3526"/>
+ <source>GAUSSIAN</source>
+ <translation>ГАУС</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3529"/>
+ <source>SCALEFORCE</source>
+ <translation>SCALEFORCE</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3532"/>
+ <source>FSR</source>
+ <translation>FSR</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3544"/>
+ <location filename="../../src/yuzu/main.cpp" line="3550"/>
+ <source>NO AA</source>
+ <translation>БЕЗ ЗГЛАДЖУВАННЯ</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3547"/>
+ <source>FXAA</source>
+ <translation>FXAA</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3624"/>
+ <source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
+ <translation>Гра, яку ви намагаєтеся завантажити, вимагає, щоб додаткові файли були здамплені з вашого Switch перед початком гри. &lt;br/&gt;&lt;br/&gt;Для отримання додаткової інформації про дамп цих файлів див. наступну вікі: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Дамп системних архівів і загальних шрифтів з консолі&lt;/a&gt;. &lt;br/&gt;&lt;br/&gt;Хочете повернутися до списку ігор? Продовження емуляції може призвести до збоїв, пошкодження збережених даних або інших помилок.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3639"/>
+ <source>yuzu was unable to locate a Switch system archive. %1</source>
+ <translation>yuzu не вдалося знайти системний архів Switch. %1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <source>yuzu was unable to locate a Switch system archive: %1. %2</source>
+ <translation>yuzu не вдалося знайти системний архів Switch: %1. %2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3645"/>
+ <source>System Archive Not Found</source>
+ <translation>Системний архів не знайдено</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3647"/>
+ <source>System Archive Missing</source>
+ <translation>Відсутній системний архів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3653"/>
+ <source>yuzu was unable to locate the Switch shared fonts. %1</source>
+ <translation>yuzu не вдалося знайти загальні шрифти Switch. %1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3654"/>
+ <source>Shared Fonts Not Found</source>
+ <translation>Загальні шрифти не знайдено</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3656"/>
+ <source>Shared Font Missing</source>
+ <translation>Загальні шрифти відсутні</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3662"/>
+ <source>Fatal Error</source>
+ <translation>Фатальна помилка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3663"/>
+ <source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
+ <translation>yuzu зіткнувся з фатальною помилкою, перевірте журнал для отримання більш детальної інформації. Для отримання додаткової інформації про доступ до журналу відкрийте наступну сторінку: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Як завантажити файл журналу&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Ви хочете повернутися до списку ігор? Продовження емуляції може призвести до збоїв, пошкодження збережень або інших помилок.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3672"/>
+ <source>Fatal Error encountered</source>
+ <translation>Сталася фатальна помилка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3695"/>
+ <source>Confirm Key Rederivation</source>
+ <translation>Підтвердіть перерахунок ключа</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3696"/>
+ <source>You are about to force rederive all of your keys.
+If you do not know what this means or what you are doing,
+this is a potentially destructive action.
+Please make sure this is what you want
+and optionally make backups.
+
+This will delete your autogenerated key files and re-run the key derivation module.</source>
+ <translation>Ви збираєтеся примусово перерахувати всі ваші ключі.
+Якщо ви не знаєте, що це означає або що ви робите,
+це потенційно руйнівна дія.
+Будь ласка, переконайтеся, що це те, що ви хочете
+і, по бажанню, зробіть резервні копії.
+
+Це видалить ваші автоматично згенеровані файли ключів і повторно запустить модуль розрахунку ключів.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3728"/>
+ <source>Missing fuses</source>
+ <translation>Відсутні запобіжники</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3731"/>
+ <source> - Missing BOOT0</source>
+ <translation>- Відсутній BOOT0</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3734"/>
+ <source> - Missing BCPKG2-1-Normal-Main</source>
+ <translation>- Відсутній BCPKG2-1-Normal-Main</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3737"/>
+ <source> - Missing PRODINFO</source>
+ <translation> - Відсутній PRODINFO</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <source>Derivation Components Missing</source>
+ <translation>Компоненти розрахунку відсутні</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3742"/>
+ <source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
+ <translation>Ключі шифрування відсутні.&lt;br&gt;Будь ласка, дотримуйтесь &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;короткого керівництва користувача yuzu&lt;/a&gt;, щоб отримати всі ваші ключі, прошивку та ігри&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3751"/>
+ <source>Deriving keys...
+This may take up to a minute depending
+on your system&apos;s performance.</source>
+ <translation>Отримання ключів...
+Це може зайняти до хвилини залежно від
+від продуктивності вашої системи.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3753"/>
+ <source>Deriving Keys</source>
+ <translation>Отримання ключів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3798"/>
+ <source>Select RomFS Dump Target</source>
+ <translation>Оберіть ціль для дампа RomFS</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3799"/>
+ <source>Please select which RomFS you would like to dump.</source>
+ <translation>Будь ласка, виберіть, який RomFS ви хочете здампити.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3814"/>
+ <source>Are you sure you want to close yuzu?</source>
+ <translation>Ви впевнені, що хочете закрити yuzu?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3815"/>
+ <location filename="../../src/yuzu/main.cpp" line="3913"/>
+ <location filename="../../src/yuzu/main.cpp" line="3926"/>
+ <source>yuzu</source>
+ <translation>yuzu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
+ <translation>Ви впевнені, що хочете зупинити емуляцію? Будь-який незбережений прогрес буде втрачено.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.cpp" line="3923"/>
+ <source>The currently running application has requested yuzu to not exit.
+
+Would you like to bypass this and exit anyway?</source>
+ <translation>Запущений на даний момент додаток просить yuzu не завершувати роботу.
+
+Чи хочете ви обійти це і вийти в будь-якому випадку?</translation>
+ </message>
+</context>
+<context>
+ <name>GRenderWindow</name>
+ <message>
+ <location filename="../../src/yuzu/bootmanager.cpp" line="1047"/>
+ <source>OpenGL not available!</source>
+ <translation>OpenGL недоступний!</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/bootmanager.cpp" line="1048"/>
+ <source>yuzu has not been compiled with OpenGL support.</source>
+ <translation>yuzu не було зібрано з підтримкою OpenGL.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/bootmanager.cpp" line="1067"/>
+ <location filename="../../src/yuzu/bootmanager.cpp" line="1087"/>
+ <source>Error while initializing OpenGL!</source>
+ <translation>Помилка під час ініціалізації OpenGL!</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/bootmanager.cpp" line="1068"/>
+ <source>Your GPU may not support OpenGL, or you do not have the latest graphics driver.</source>
+ <translation>Ваш ГП може не підтримувати OpenGL, або у вас встановлено застарілий графічний драйвер.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/bootmanager.cpp" line="1077"/>
+ <source>Error while initializing OpenGL 4.6!</source>
+ <translation>Помилка під час ініціалізації OpenGL 4.6!</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/bootmanager.cpp" line="1078"/>
+ <source>Your GPU may not support OpenGL 4.6, or you do not have the latest graphics driver.&lt;br&gt;&lt;br&gt;GL Renderer:&lt;br&gt;%1</source>
+ <translation>Ваш ГП може не підтримувати OpenGL 4.6, або у вас встановлено застарілий графічний драйвер.&lt;br&gt;&lt;br&gt;Рендерер GL:&lt;br&gt;%1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/bootmanager.cpp" line="1088"/>
+ <source>Your GPU may not support one or more required OpenGL extensions. Please ensure you have the latest graphics driver.&lt;br&gt;&lt;br&gt;GL Renderer:&lt;br&gt;%1&lt;br&gt;&lt;br&gt;Unsupported extensions:&lt;br&gt;%2</source>
+ <translation>Ваш ГП може не підтримувати одне або кілька необхідних розширень OpenGL. Будь ласка, переконайтеся в тому, що у вас встановлено останній графічний драйвер.&lt;br&gt;&lt;br&gt;Рендерер GL:&lt;br&gt;%1&lt;br&gt;&lt;br&gt;Розширення, що не підтримуються:&lt;br&gt;%2</translation>
+ </message>
+</context>
+<context>
+ <name>GameList</name>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="532"/>
+ <source>Favorite</source>
+ <translation>Улюблені</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="534"/>
+ <source>Start Game</source>
+ <translation>Запустити гру</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="536"/>
+ <source>Start Game without Custom Configuration</source>
+ <translation>Запустити гру без користувацького налаштування</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="538"/>
+ <source>Open Save Data Location</source>
+ <translation>Відкрити папку для збережень</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="539"/>
+ <source>Open Mod Data Location</source>
+ <translation>Відкрити папку для модів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="541"/>
+ <source>Open Transferable Pipeline Cache</source>
+ <translation>Відкрити переносний кеш конвеєра</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="543"/>
+ <source>Remove</source>
+ <translation>Видалити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="544"/>
+ <source>Remove Installed Update</source>
+ <translation>Видалити встановлене оновлення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="545"/>
+ <source>Remove All Installed DLC</source>
+ <translation>Видалити усі DLC</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="546"/>
+ <source>Remove Custom Configuration</source>
+ <translation>Видалити користувацьке налаштування</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="547"/>
+ <source>Remove OpenGL Pipeline Cache</source>
+ <translation>Видалити кеш конвеєра OpenGL</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="548"/>
+ <source>Remove Vulkan Pipeline Cache</source>
+ <translation>Видалити кеш конвеєра Vulkan</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="550"/>
+ <source>Remove All Pipeline Caches</source>
+ <translation>Видалити весь кеш конвеєра </translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="551"/>
+ <source>Remove All Installed Contents</source>
+ <translation>Видалити весь встановлений вміст</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="552"/>
+ <location filename="../../src/yuzu/game_list.cpp" line="553"/>
+ <source>Dump RomFS</source>
+ <translation>Дамп RomFS</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="554"/>
+ <source>Dump RomFS to SDMC</source>
+ <translation>Здампити RomFS у SDMC</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="555"/>
+ <source>Copy Title ID to Clipboard</source>
+ <translation>Скопіювати ідентифікатор додатку в буфер обміну</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="556"/>
+ <source>Navigate to GameDB entry</source>
+ <translation>Перейти до сторінки GameDB</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="558"/>
+ <source>Properties</source>
+ <translation>Властивості</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="630"/>
+ <source>Scan Subfolders</source>
+ <translation>Сканувати підпапки</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="631"/>
+ <source>Remove Game Directory</source>
+ <translation>Видалити директорію гри</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="650"/>
+ <source>▲ Move Up</source>
+ <translation>▲ Перемістити вверх</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="651"/>
+ <source>▼ Move Down</source>
+ <translation>▼ Перемістити вниз</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="652"/>
+ <source>Open Directory Location</source>
+ <translation>Відкрити розташування папки</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="697"/>
+ <source>Clear</source>
+ <translation>Очистити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="761"/>
+ <source>Name</source>
+ <translation>Назва</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="762"/>
+ <source>Compatibility</source>
+ <translation>Сумісність</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="763"/>
+ <source>Add-ons</source>
+ <translation>Доповнення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="764"/>
+ <source>File type</source>
+ <translation>Тип файлу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="765"/>
+ <source>Size</source>
+ <translation>Розмір</translation>
+ </message>
+</context>
+<context>
+ <name>GameListItemCompat</name>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <source>Perfect</source>
+ <translation>Ідеально</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="149"/>
+ <source>Game functions flawless with no audio or graphical glitches, all tested functionality works as intended without
+any workarounds needed.</source>
+ <translation>Гра працює бездоганно, без звукових або графічних артефактів, усі протестовані функції працюють без обхідних шляхів.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
+ <source>Great</source>
+ <translation>Чудово</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="150"/>
+ <source>Game functions with minor graphical or audio glitches and is playable from start to finish. May require some
+workarounds.</source>
+ <translation>Гра працює з невеликими графічними або звуковими артефактами і може бути пройдена від
+ початку до кінця. Можуть знадобитися обхідні шляхи.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <source>Okay</source>
+ <translation>Добре</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="151"/>
+ <source>Game functions with major graphical or audio glitches, but game is playable from start to finish with
+workarounds.</source>
+ <translation>Гра працює з істотними графічними або звуковими артефактами, але може бути пройдена
+з використанням обхідних шляхів.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <source>Bad</source>
+ <translation>Погано</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="152"/>
+ <source>Game functions, but with major graphical or audio glitches. Unable to progress in specific areas due to glitches
+even with workarounds.</source>
+ <translation>Гра працює, але з істотними графічними або звуковими артефактами.
+У деяких частинах неможливо просунутися навіть з обхідними шляхами.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
+ <source>Intro/Menu</source>
+ <translation>Вступ/Меню</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="153"/>
+ <source>Game is completely unplayable due to major graphical or audio glitches. Unable to progress past the Start
+Screen.</source>
+ <translation>У гру неможливо грати через графічні або звукові артефакти.
+Неможливо просунутися далі стартового екрана.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="154"/>
+ <source>Won&apos;t Boot</source>
+ <translation>Не запускається</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="154"/>
+ <source>The game crashes when attempting to startup.</source>
+ <translation>Гра вилітає під час запуску.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <source>Not Tested</source>
+ <translation>Не перевірено</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="155"/>
+ <source>The game has not yet been tested.</source>
+ <translation>Гру ще не перевіряли на сумісність.</translation>
+ </message>
+</context>
+<context>
+ <name>GameListPlaceholder</name>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="935"/>
+ <source>Double-click to add a new folder to the game list</source>
+ <translation>Натисніть двічі, щоб додати нову папку до списку ігор</translation>
+ </message>
+</context>
+<context>
+ <name>GameListSearchField</name>
+ <message numerus="yes">
+ <location filename="../../src/yuzu/game_list.cpp" line="86"/>
+ <source>%1 of %n result(s)</source>
+ <translation><numerusform>%1 із %n результат(ів)</numerusform><numerusform>%1 із %n результат(ів)</numerusform><numerusform>%1 із %n результат(ів)</numerusform><numerusform>%1 із %n результат(ів)</numerusform></translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="777"/>
+ <source>Filter:</source>
+ <translation>Пошук:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list.cpp" line="778"/>
+ <source>Enter pattern to filter</source>
+ <translation>Введіть текст для пошуку</translation>
+ </message>
+</context>
+<context>
+ <name>HostRoom</name>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.ui" line="14"/>
+ <source>Create Room</source>
+ <translation>Створити кімнату</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.ui" line="37"/>
+ <source>Room Name</source>
+ <translation>Назва кімнати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.ui" line="51"/>
+ <source>Preferred Game</source>
+ <translation>Переважна гра</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.ui" line="61"/>
+ <source>Max Players</source>
+ <translation>Максимальна кількість гравців</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.ui" line="91"/>
+ <source>Username</source>
+ <translation>Ім&apos;я користувача</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.ui" line="101"/>
+ <source>(Leave blank for open game)</source>
+ <translation>(Залиште порожнім для відкритої гри)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.ui" line="118"/>
+ <source>Password</source>
+ <translation>Пароль</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.ui" line="125"/>
+ <source>Port</source>
+ <translation>Порт</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.ui" line="139"/>
+ <source>Room Description</source>
+ <translation>Опис кімнати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.ui" line="153"/>
+ <source>Load Previous Ban List</source>
+ <translation>Завантажити попередній список заблокованих</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.ui" line="184"/>
+ <source>Public</source>
+ <translation>Публічна</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.ui" line="189"/>
+ <source>Unlisted</source>
+ <translation>Прихована</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.ui" line="197"/>
+ <source>Host Room</source>
+ <translation>Створити кімнату</translation>
+ </message>
+</context>
+<context>
+ <name>HostRoomWindow</name>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
+ <source>Error</source>
+ <translation>Помилка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
+ <source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
+Debug Message: </source>
+ <translation>Не вдалося оголосити кімнату в публічному фойє. Щоб хостити публічну кімнату, у вас має бути діючий обліковий запис yuzu, налаштований в Емуляція -&gt; Налаштування -&gt; Мережа. Якщо ви не хочете оголошувати кімнату в публічному лобі, виберіть замість цього прихований тип.
+Повідомлення налагодження:</translation>
+ </message>
+</context>
+<context>
+ <name>Hotkeys</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
+ <source>Audio Mute/Unmute</source>
+ <translation>Увімкнення/вимкнення звуку</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <source>Main Window</source>
+ <translation>Основне вікно</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <source>Audio Volume Down</source>
+ <translation>Зменшити гучність звуку</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <source>Audio Volume Up</source>
+ <translation>Підвищити гучність звуку</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <source>Capture Screenshot</source>
+ <translation>Зробити знімок екрану</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <source>Change Adapting Filter</source>
+ <translation>Змінити адаптуючий фільтр</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <source>Change Docked Mode</source>
+ <translation>Змінити режим консолі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <source>Change GPU Accuracy</source>
+ <translation>Змінити точність ГП</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <source>Continue/Pause Emulation</source>
+ <translation>Продовження/Пауза емуляції</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <source>Exit Fullscreen</source>
+ <translation>Вийти з повноекранного режиму</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <source>Exit yuzu</source>
+ <translation>Вийти з yuzu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <source>Fullscreen</source>
+ <translation>Повний екран</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <source>Load File</source>
+ <translation>Завантажити файл</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <source>Load/Remove Amiibo</source>
+ <translation>Завантажити/видалити Amiibo</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <source>Restart Emulation</source>
+ <translation>Перезапустити емуляцію</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <source>Stop Emulation</source>
+ <translation>Зупинити емуляцію</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <source>TAS Record</source>
+ <translation>Запис TAS</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <source>TAS Reset</source>
+ <translation>Скидання TAS</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <source>TAS Start/Stop</source>
+ <translation>Старт/Стоп TAS</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <source>Toggle Filter Bar</source>
+ <translation>Переключити панель пошуку</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <source>Toggle Framerate Limit</source>
+ <translation>Переключити обмеження частоти кадрів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <source>Toggle Mouse Panning</source>
+ <translation>Переключити панорамування миші</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <source>Toggle Status Bar</source>
+ <translation>Переключити панель стану</translation>
+ </message>
+</context>
+<context>
+ <name>InstallDialog</name>
+ <message>
+ <location filename="../../src/yuzu/install_dialog.cpp" line="29"/>
+ <source>Please confirm these are the files you wish to install.</source>
+ <translation>Будь ласка, переконайтеся, що це ті файли, які ви хочете встановити.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/install_dialog.cpp" line="32"/>
+ <source>Installing an Update or DLC will overwrite the previously installed one.</source>
+ <translation>Встановлення оновлення або завантажуваного контенту перезапише раніше встановлене.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/install_dialog.cpp" line="36"/>
+ <source>Install</source>
+ <translation>Встановити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/install_dialog.cpp" line="50"/>
+ <source>Install Files to NAND</source>
+ <translation>Встановити файли в NAND</translation>
+ </message>
+</context>
+<context>
+ <name>LimitableInputDialog</name>
+ <message>
+ <location filename="../../src/yuzu/util/limitable_input_dialog.cpp" line="61"/>
+ <source>The text can't contain any of the following characters:
+%1</source>
+ <translation>У тексті неприпустимі такі символи:
+%1</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingScreen</name>
+ <message>
+ <location filename="../../src/yuzu/loading_screen.ui" line="84"/>
+ <source>Loading Shaders 387 / 1628</source>
+ <translation>Завантаження шейдерів 387 / 1628</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/loading_screen.ui" line="121"/>
+ <source>Loading Shaders %v out of %m</source>
+ <translation>Завантаження шейдерів %v із %m</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/loading_screen.ui" line="135"/>
+ <source>Estimated Time 5m 4s</source>
+ <translation>Залишилося приблизно 5м 4с</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/loading_screen.cpp" line="83"/>
+ <source>Loading...</source>
+ <translation>Завантаження...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/loading_screen.cpp" line="84"/>
+ <source>Loading Shaders %1 / %2</source>
+ <translation>Завантаження шейдерів %1 / %2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/loading_screen.cpp" line="85"/>
+ <source>Launching...</source>
+ <translation>Запуск...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/loading_screen.cpp" line="170"/>
+ <source>Estimated Time %1</source>
+ <translation>Залишилося приблизно %1</translation>
+ </message>
+</context>
+<context>
+ <name>Lobby</name>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.ui" line="14"/>
+ <source>Public Room Browser</source>
+ <translation>Браузер публічних кімнат</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.ui" line="32"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.ui" line="39"/>
+ <source>Nickname</source>
+ <translation>Псевдонім</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.ui" line="59"/>
+ <source>Filters</source>
+ <translation>Фільтри</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.ui" line="66"/>
+ <source>Search</source>
+ <translation>Пошук</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.ui" line="76"/>
+ <source>Games I Own</source>
+ <translation>Ігри, якими я володію</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.ui" line="83"/>
+ <source>Hide Full Rooms</source>
+ <translation>Приховати повні кімнати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.ui" line="103"/>
+ <source>Refresh Lobby</source>
+ <translation>Оновити фойє</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="112"/>
+ <source>Password Required to Join</source>
+ <translation>Для входу необхідний пароль</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="112"/>
+ <source>Password:</source>
+ <translation>Пароль:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="215"/>
+ <source>Players</source>
+ <translation>Гравці</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
+ <source>Room Name</source>
+ <translation>Назва кімнати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="217"/>
+ <source>Preferred Game</source>
+ <translation>Переважна гра</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="218"/>
+ <source>Host</source>
+ <translation>Хост</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="225"/>
+ <source>Refreshing</source>
+ <translation>Оновлення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="282"/>
+ <source>Refresh List</source>
+ <translation>Оновити список</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="14"/>
+ <source>yuzu</source>
+ <translation>yuzu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="44"/>
+ <source>&amp;File</source>
+ <translation>[&amp;F] Файл</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="48"/>
+ <source>&amp;Recent Files</source>
+ <translation>[&amp;R] Нещодавні файли</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="67"/>
+ <source>&amp;Emulation</source>
+ <translation>[&amp;E] Емуляція</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="78"/>
+ <source>&amp;View</source>
+ <translation>[&amp;V] Вигляд</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="82"/>
+ <source>&amp;Reset Window Size</source>
+ <translation>[&amp;R] Скинути розмір вікна</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="87"/>
+ <source>&amp;Debugging</source>
+ <translation>[&amp;D] Налагодження</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="92"/>
+ <source>Reset Window Size to &amp;720p</source>
+ <translation>Скинути розмір вікна до &amp;720p</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="95"/>
+ <source>Reset Window Size to 720p</source>
+ <translation>Скинути розмір вікна до 720p</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="100"/>
+ <source>Reset Window Size to &amp;900p</source>
+ <translation>Скинути розмір вікна до &amp;900p</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="103"/>
+ <source>Reset Window Size to 900p</source>
+ <translation>Скинути розмір вікна до 900p</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="108"/>
+ <source>Reset Window Size to &amp;1080p</source>
+ <translation>Скинути розмір вікна до &amp;1080p</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="111"/>
+ <source>Reset Window Size to 1080p</source>
+ <translation>Скинути розмір вікна до 1080p</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="128"/>
+ <source>&amp;Multiplayer</source>
+ <translation>[&amp;M] Мультиплеєр</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="139"/>
+ <source>&amp;Tools</source>
+ <translation>[&amp;T] Інструменти</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="143"/>
+ <source>&amp;TAS</source>
+ <translation>[&amp;T] TAS</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="158"/>
+ <source>&amp;Help</source>
+ <translation>[&amp;H] Допомога</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="179"/>
+ <source>&amp;Install Files to NAND...</source>
+ <translation>[&amp;I] Встановити файли в NAND...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="184"/>
+ <source>L&amp;oad File...</source>
+ <translation>[&amp;O] Завантажити файл...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="189"/>
+ <source>Load &amp;Folder...</source>
+ <translation>[&amp;F] Завантажити папку...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="194"/>
+ <source>E&amp;xit</source>
+ <translation>[&amp;X] Вихід</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="202"/>
+ <source>&amp;Pause</source>
+ <translation>[&amp;P] Пауза</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="210"/>
+ <source>&amp;Stop</source>
+ <translation>[&amp;S] Стоп</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="215"/>
+ <source>&amp;Reinitialize keys...</source>
+ <translation>[&amp;R] Переініціалізувати ключі...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="220"/>
+ <source>&amp;About yuzu</source>
+ <translation>[&amp;A] Про yuzu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="228"/>
+ <source>Single &amp;Window Mode</source>
+ <translation>[&amp;W] Режим одного вікна</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="233"/>
+ <source>Con&amp;figure...</source>
+ <translation>[&amp;F] Налаштування...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="241"/>
+ <source>Display D&amp;ock Widget Headers</source>
+ <translation>[&amp;O] Відображати заголовки віджетів дока</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="249"/>
+ <source>Show &amp;Filter Bar</source>
+ <translation>[&amp;F] Показати панель пошуку</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="257"/>
+ <source>Show &amp;Status Bar</source>
+ <translation>[&amp;S] Показати панель статусу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="260"/>
+ <source>Show Status Bar</source>
+ <translation>Показати панель статусу</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="268"/>
+ <source>&amp;Browse Public Game Lobby</source>
+ <translation>[&amp;B] Переглянути публічні ігрові фойє</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="276"/>
+ <source>&amp;Create Room</source>
+ <translation>[&amp;C] Створити кімнату</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="284"/>
+ <source>&amp;Leave Room</source>
+ <translation>[&amp;L] Залишити кімнату</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="289"/>
+ <source>&amp;Direct Connect to Room</source>
+ <translation>[&amp;D] Пряме під&apos;єднання до кімнати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="297"/>
+ <source>&amp;Show Current Room</source>
+ <translation>[&amp;S] Показати поточну кімнату</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="305"/>
+ <source>F&amp;ullscreen</source>
+ <translation>[&amp;U] Повноекранний</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="313"/>
+ <source>&amp;Restart</source>
+ <translation>[&amp;R] Перезапустити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="321"/>
+ <source>Load/Remove &amp;Amiibo...</source>
+ <translation>[&amp;A] Завантажити/Видалити Amiibo...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="329"/>
+ <source>&amp;Report Compatibility</source>
+ <translation>[&amp;R] Повідомити про сумісність</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="337"/>
+ <source>Open &amp;Mods Page</source>
+ <translation>[&amp;M] Відкрити сторінку модів</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="342"/>
+ <source>Open &amp;Quickstart Guide</source>
+ <translation>[&amp;Q] Відкрити посібник користувача</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="347"/>
+ <source>&amp;FAQ</source>
+ <translation>[&amp;F] ЧАП</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="352"/>
+ <source>Open &amp;yuzu Folder</source>
+ <translation>[&amp;Y] Відкрити папку yuzu</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="360"/>
+ <source>&amp;Capture Screenshot</source>
+ <translation>[&amp;C] Зробити знімок екрану</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="365"/>
+ <source>&amp;Configure TAS...</source>
+ <translation>[&amp;C] Налаштування TAS...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="373"/>
+ <source>Configure C&amp;urrent Game...</source>
+ <translation>[&amp;U] Налаштувати поточну гру...</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="381"/>
+ <source>&amp;Start</source>
+ <translation>[&amp;S] Почати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="389"/>
+ <source>&amp;Reset</source>
+ <translation>[&amp;S] Скинути</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/main.ui" line="397"/>
+ <source>R&amp;ecord</source>
+ <translation>[&amp;E] Запис</translation>
+ </message>
+</context>
+<context>
+ <name>MicroProfileDialog</name>
+ <message>
+ <location filename="../../src/yuzu/debugger/profiler.cpp" line="50"/>
+ <source>&amp;MicroProfile</source>
+ <translation>[&amp;M] MicroProfile</translation>
+ </message>
+</context>
+<context>
+ <name>ModerationDialog</name>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="6"/>
+ <source>Moderation</source>
+ <translation>Модерація</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="20"/>
+ <source>Ban List</source>
+ <translation>Список заблокованих</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="41"/>
+ <location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="73"/>
+ <source>Refreshing</source>
+ <translation>Оновлення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/moderation_dialog.ui" line="51"/>
+ <source>Unban</source>
+ <translation>Розблокувати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="40"/>
+ <source>Subject</source>
+ <translation>Суб&apos;єкт</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="41"/>
+ <source>Type</source>
+ <translation>Тип</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="83"/>
+ <source>Forum Username</source>
+ <translation>Ім&apos;я користувача на форумі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="88"/>
+ <source>IP Address</source>
+ <translation>IP-адреса</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/moderation_dialog.cpp" line="95"/>
+ <source>Refresh</source>
+ <translation>Оновити</translation>
+ </message>
+</context>
+<context>
+ <name>MultiplayerState</name>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="90"/>
+ <source>Current connection status</source>
+ <translation>Поточний стан з&apos;єднання</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="117"/>
+ <source>Not Connected. Click here to find a room!</source>
+ <translation>Не з&apos;єднано. Натисніть тут, щоб знайти кімнату!</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
+ <source>Not Connected</source>
+ <translation>Не з&apos;єднано</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="129"/>
+ <source>Connected</source>
+ <translation>З&apos;єднано</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="136"/>
+ <source>New Messages Received</source>
+ <translation>Отримано нові повідомлення</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="207"/>
+ <source>Error</source>
+ <translation>Помилка</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="208"/>
+ <source>Failed to update the room information. Please check your Internet connection and try hosting the room again.
+Debug Message: </source>
+ <translation>Не вдалося оновити інформацію про кімнату. Будь ласка, перевірте підключення до Інтернету та спробуйте знову зайти в кімнату.
+Повідомлення налагодження:</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkMessage</name>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="11"/>
+ <source>Username is not valid. Must be 4 to 20 alphanumeric characters.</source>
+ <translation>Ім&apos;я користувача неприпустиме. Має бути від 4 до 20 буквено-цифрових символів.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="13"/>
+ <source>Room name is not valid. Must be 4 to 20 alphanumeric characters.</source>
+ <translation>Назва кімнати неприпустима. Має бути від 4 до 20 буквено-цифрових символів.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="15"/>
+ <source>Username is already in use or not valid. Please choose another.</source>
+ <translation>Ім&apos;я користувача вже використовується або недійсне. Будь ласка, виберіть інше.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="17"/>
+ <source>IP is not a valid IPv4 address.</source>
+ <translation>IP-адреса не є дійсною адресою IPv4.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="19"/>
+ <source>Port must be a number between 0 to 65535.</source>
+ <translation>Порт повинен бути числом від 0 до 65535.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="20"/>
+ <source>You must choose a Preferred Game to host a room. If you do not have any games in your game list yet, add a game folder by clicking on the plus icon in the game list.</source>
+ <translation>Ви повинні вибрати бажану гру, щоб хостити кімнату. Якщо у вашому списку ігор ще немає жодної гри, додайте папку з грою, натиснувши на значок плюса у списку ігор.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="24"/>
+ <source>Unable to find an internet connection. Check your internet settings.</source>
+ <translation>Неможливо знайти підключення до Інтернету. Перевірте налаштування інтернету.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="26"/>
+ <source>Unable to connect to the host. Verify that the connection settings are correct. If you still cannot connect, contact the room host and verify that the host is properly configured with the external port forwarded.</source>
+ <translation>Неможливо підключитися до хоста. Перевірте правильність налаштувань підключення. Якщо під&apos;єднання, як і раніше, неможливе, зв&apos;яжіться з хостом кімнати та переконайтеся, що хост правильно налаштований із прокинутим зовнішнім портом.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="30"/>
+ <source>Unable to connect to the room because it is already full.</source>
+ <translation>Неможливо підключитися до кімнати, оскільки вона вже заповнена.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="32"/>
+ <source>Creating a room failed. Please retry. Restarting yuzu might be necessary.</source>
+ <translation>Створення кімнати не вдалося. Будь ласка, повторіть спробу. Можливо, потрібно перезапустити yuzu.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="34"/>
+ <source>The host of the room has banned you. Speak with the host to unban you or try a different room.</source>
+ <translation>Хост кімнати заблокував вас. Поговоріть із хостом, щоб він розблокував вас, або спробуйте іншу кімнату.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="37"/>
+ <source>Version mismatch! Please update to the latest version of yuzu. If the problem persists, contact the room host and ask them to update the server.</source>
+ <translation>Невідповідність версій! Будь ласка, оновіть yuzu до останньої версії. Якщо проблема не зникне, зверніться до хосту кімнати і попросіть його оновити сервер.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="39"/>
+ <source>Incorrect password.</source>
+ <translation>Невірний пароль.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="40"/>
+ <source>An unknown error occurred. If this error continues to occur, please open an issue</source>
+ <translation>Сталася невідома помилка. Якщо ця помилка продовжує виникати, будь ласка, відкрийте проблему</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="43"/>
+ <source>Connection to room lost. Try to reconnect.</source>
+ <translation>З&apos;єднання з кімнатою втрачено. Спробуйте підключитися знову.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="45"/>
+ <source>You have been kicked by the room host.</source>
+ <translation>Вас вигнав хост кімнати.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="47"/>
+ <source>IP address is already in use. Please choose another.</source>
+ <translation>IP-адреса вже використовується. Будь ласка, виберіть іншу.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="49"/>
+ <source>You do not have enough permission to perform this action.</source>
+ <translation>У вас немає достатніх дозволів для виконання цієї дії.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="50"/>
+ <source>The user you are trying to kick/ban could not be found.
+They may have left the room.</source>
+ <translation>Користувача, якого ви намагаєтеся вигнати/заблокувати, не знайдено.
+Можливо, вони покинули кімнату.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="52"/>
+ <source>No valid network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation>Не вибрано припустимий інтерфейс мережі.
+Будь ласка, перейдіть у Налаштування -&gt; Система -&gt; Мережа та зробіть вибір.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation>Гру вже запущено</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation>Приєднуватися до кімнати, коли гру вже запущено, не рекомендується, це може призвести до неправильної роботи функції кімнати.
+Все одно продовжити?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
+ <source>Leave Room</source>
+ <translation>Залишити кімнату</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
+ <source>You are about to close the room. Any network connections will be closed.</source>
+ <translation>Ви збираєтеся закрити кімнату. Усі мережеві підключення буде закрито.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
+ <source>Disconnect</source>
+ <translation>Від&apos;єднатися</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
+ <source>You are about to leave the room. Any network connections will be closed.</source>
+ <translation>Ви збираєтеся покинути кімнату. Усі мережеві підключення буде закрито.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkMessage::ErrorManager</name>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
+ <source>Error</source>
+ <translation>Помилка</translation>
+ </message>
+</context>
+<context>
+ <name>OverlayDialog</name>
+ <message>
+ <location filename="../../src/yuzu/util/overlay_dialog.ui" line="14"/>
+ <source>Dialog</source>
+ <translation>Діалог</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/util/overlay_dialog.ui" line="134"/>
+ <location filename="../../src/yuzu/util/overlay_dialog.ui" line="353"/>
+ <source>Cancel</source>
+ <translation>Скасувати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/util/overlay_dialog.ui" line="152"/>
+ <location filename="../../src/yuzu/util/overlay_dialog.ui" line="371"/>
+ <source>OK</source>
+ <translation>ОК</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/util/overlay_dialog.ui" line="313"/>
+ <source>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:18pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:18pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+</context>
+<context>
+ <name>PlayerControlPreview</name>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player_widget.cpp" line="1575"/>
+ <source>START/PAUSE</source>
+ <translation>СТАРТ/ПАУЗА</translation>
+ </message>
+</context>
+<context>
+ <name>QObject</name>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby_p.h" line="236"/>
+ <source>%1 is not playing a game</source>
+ <translation>%1 не грає у гру</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/lobby_p.h" line="238"/>
+ <source>%1 is playing %2</source>
+ <translation>%1 грає в %2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="142"/>
+ <source>Not playing a game</source>
+ <translation>Не грає в гру</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="242"/>
+ <source>Installed SD Titles</source>
+ <translation>Встановлені SD ігри</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="250"/>
+ <source>Installed NAND Titles</source>
+ <translation>Встановлені NAND ігри</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="258"/>
+ <source>System Titles</source>
+ <translation>Системні ігри</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="301"/>
+ <source>Add New Game Directory</source>
+ <translation>Додати нову папку з іграми</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/game_list_p.h" line="324"/>
+ <source>Favorites</source>
+ <translation>Улюблені</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="21"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="30"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="41"/>
+ <source>Shift</source>
+ <translation>Shift</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="23"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="32"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="43"/>
+ <source>Ctrl</source>
+ <translation>Ctrl</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="25"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="45"/>
+ <source>Alt</source>
+ <translation>Alt</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="35"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
+ <source>[not set]</source>
+ <translation>[не задано]</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="47"/>
+ <source>Hat %1 %2</source>
+ <translation>Напр. %1 %2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="54"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="407"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
+ <source>Axis %1%2</source>
+ <translation>Ось %1%2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="60"/>
+ <source>Button %1</source>
+ <translation>Кнопка %1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_touch_from_button.cpp" line="66"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
+ <source>[unknown]</source>
+ <translation>[невідомо]</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="45"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="56"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="124"/>
+ <source>Left</source>
+ <translation>Вліво</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="47"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="127"/>
+ <source>Right</source>
+ <translation>Вправо</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="49"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="133"/>
+ <source>Down</source>
+ <translation>Вниз</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="130"/>
+ <source>Up</source>
+ <translation>Вгору</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="53"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="64"/>
+ <source>Z</source>
+ <translation>Z</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="55"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="66"/>
+ <source>R</source>
+ <translation>R</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="68"/>
+ <source>L</source>
+ <translation>L</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="70"/>
+ <source>A</source>
+ <translation>A</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="72"/>
+ <source>B</source>
+ <translation>B</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="74"/>
+ <source>X</source>
+ <translation>X</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="65"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="76"/>
+ <source>Y</source>
+ <translation>Y</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="78"/>
+ <source>Start</source>
+ <translation>Start</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="69"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="80"/>
+ <source>L1</source>
+ <translation>L1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="82"/>
+ <source>L2</source>
+ <translation>L2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="73"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="84"/>
+ <source>L3</source>
+ <translation>L3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="86"/>
+ <source>R1</source>
+ <translation>R1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="88"/>
+ <source>R2</source>
+ <translation>R2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="90"/>
+ <source>R3</source>
+ <translation>R3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="92"/>
+ <source>Circle</source>
+ <translation>Кружечок</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="94"/>
+ <source>Cross</source>
+ <translation>Хрестик</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="96"/>
+ <source>Square</source>
+ <translation>Квадратик</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="98"/>
+ <source>Triangle</source>
+ <translation>Трикутничок</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="100"/>
+ <source>Share</source>
+ <translation>Share</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="102"/>
+ <source>Options</source>
+ <translation>Options</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="118"/>
+ <source>[undefined]</source>
+ <translation>[невизначено]</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="328"/>
+ <source>%1%2</source>
+ <translation>%1%2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
+ <source>[invalid]</source>
+ <translation>[неприпустимо]</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
+ <source>%1%2Hat %3</source>
+ <translation>%1%2Напр. %3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
+ <source>%1%2Axis %3</source>
+ <translation>%1%2Ось %3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
+ <source>%1%2Axis %3,%4,%5</source>
+ <translation>%1%2Ось %3,%4,%5</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
+ <source>%1%2Motion %3</source>
+ <translation>%1%2Рух %3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
+ <source>%1%2Button %3</source>
+ <translation>%1%2Кнопка %3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
+ <source>[unused]</source>
+ <translation>[не використаний]</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="104"/>
+ <source>Home</source>
+ <translation>Home</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="106"/>
+ <source>Touch</source>
+ <translation>Сенсор</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="108"/>
+ <source>Wheel</source>
+ <comment>Indicates the mouse wheel</comment>
+ <translation>Коліщатко</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="110"/>
+ <source>Backward</source>
+ <translation>Назад</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="112"/>
+ <source>Forward</source>
+ <translation>Вперед</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="114"/>
+ <source>Task</source>
+ <translation>Задача</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="116"/>
+ <source>Extra</source>
+ <translation>Додаткова</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
+ <source>%1%2%3</source>
+ <translation>%1%2%3</translation>
+ </message>
+</context>
+<context>
+ <name>QtControllerSelectorDialog</name>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="14"/>
+ <source>Controller Applet</source>
+ <translation>Аплет контролера</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="129"/>
+ <source>Supported Controller Types:</source>
+ <translation>Підтримувані типи контролерів:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="282"/>
+ <source>Players:</source>
+ <translation>Гравці:</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="300"/>
+ <source>1 - 8</source>
+ <translation>1 - 8</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="418"/>
+ <source>P4</source>
+ <translation>P4</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="514"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="711"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="912"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1222"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1459"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1656"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1857"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2054"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="414"/>
+ <source>Pro Controller</source>
+ <translation>Контролер Pro</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="519"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="716"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="917"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1227"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1464"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1661"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1862"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2059"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="418"/>
+ <source>Dual Joycons</source>
+ <translation>Подвійні Joy-Con&apos;и</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="524"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="721"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="922"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1232"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1469"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1666"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1867"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2064"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="422"/>
+ <source>Left Joycon</source>
+ <translation>Лівий Joy-Con</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="529"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="726"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="927"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1237"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1474"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1671"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1872"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2069"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="426"/>
+ <source>Right Joycon</source>
+ <translation>Правий Joy-Con</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="538"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="735"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="941"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1246"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1483"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1680"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1881"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2078"/>
+ <source>Use Current Config</source>
+ <translation>Використовувати поточну конфігурацію</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="615"/>
+ <source>P2</source>
+ <translation>P2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="812"/>
+ <source>P1</source>
+ <translation>P1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="932"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2303"/>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="430"/>
+ <source>Handheld</source>
+ <translation>Портативний</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1126"/>
+ <source>P3</source>
+ <translation>P3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1363"/>
+ <source>P7</source>
+ <translation>P7</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1560"/>
+ <source>P8</source>
+ <translation>P8</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1757"/>
+ <source>P5</source>
+ <translation>P5</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="1958"/>
+ <source>P6</source>
+ <translation>P6</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2272"/>
+ <source>Console Mode</source>
+ <translation>Режим консолі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2293"/>
+ <source>Docked</source>
+ <translation>У док-станції</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2313"/>
+ <source>Vibration</source>
+ <translation>Вібрація</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2349"/>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2395"/>
+ <source>Configure</source>
+ <translation>Налаштувати</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2359"/>
+ <source>Motion</source>
+ <translation>Рух</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2405"/>
+ <source>Profiles</source>
+ <translation>Профілі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2432"/>
+ <source>Create</source>
+ <translation>Створити</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2467"/>
+ <source>Controllers</source>
+ <translation>Контролери</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2481"/>
+ <source>1</source>
+ <translation>1</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2508"/>
+ <source>2</source>
+ <translation>2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2518"/>
+ <source>4</source>
+ <translation>4</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2528"/>
+ <source>3</source>
+ <translation>3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2538"/>
+ <source>Connected</source>
+ <translation>З&apos;єднано</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2552"/>
+ <source>5</source>
+ <translation>5</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2569"/>
+ <source>7</source>
+ <translation>7</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2586"/>
+ <source>6</source>
+ <translation>6</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.ui" line="2596"/>
+ <source>8</source>
+ <translation>8</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="434"/>
+ <source>GameCube Controller</source>
+ <translation>Контролер GameCube</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="443"/>
+ <source>Poke Ball Plus</source>
+ <translation>Poke Ball Plus</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="447"/>
+ <source>NES Controller</source>
+ <translation>Контролер NES</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="451"/>
+ <source>SNES Controller</source>
+ <translation>Контролер SNES</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="455"/>
+ <source>N64 Controller</source>
+ <translation>Контролер N64</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_controller.cpp" line="459"/>
+ <source>Sega Genesis</source>
+ <translation>Sega Genesis</translation>
+ </message>
+</context>
+<context>
+ <name>QtErrorDisplay</name>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_error.cpp" line="20"/>
+ <location filename="../../src/yuzu/applets/qt_error.cpp" line="33"/>
+ <location filename="../../src/yuzu/applets/qt_error.cpp" line="48"/>
+ <source>Error Code: %1-%2 (0x%3)</source>
+ <translation>Код помилки: %1-%2 (0x%3)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_error.cpp" line="24"/>
+ <source>An error has occurred.
+Please try again or contact the developer of the software.</source>
+ <translation>Сталася помилка.
+Будь ласка, спробуйте ще раз або зв&apos;яжіться з розробником ПЗ.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_error.cpp" line="37"/>
+ <source>An error occurred on %1 at %2.
+Please try again or contact the developer of the software.</source>
+ <translation>Сталася помилка на %1 у %2.
+Будь ласка, спробуйте ще раз або зв&apos;яжіться з розробником ПЗ.</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_error.cpp" line="52"/>
+ <source>An error has occurred.
+
+%1
+
+%2</source>
+ <translation>Сталася помилка.
+
+%1
+
+%2</translation>
+ </message>
+</context>
+<context>
+ <name>QtProfileSelectionDialog</name>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="23"/>
+ <source>%1
+%2</source>
+ <comment>%1 is the profile username, %2 is the formatted UUID (e.g. 00112233-4455-6677-8899-AABBCCDDEEFF))</comment>
+ <translation>%1
+%2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="53"/>
+ <source>Select a user:</source>
+ <translation>Оберить користувача</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="83"/>
+ <source>Users</source>
+ <translation>Користувачі</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_profile_select.cpp" line="123"/>
+ <source>Profile Selector</source>
+ <translation>Вибір профілю</translation>
+ </message>
+</context>
+<context>
+ <name>QtSoftwareKeyboardDialog</name>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_software_keyboard.ui" line="14"/>
+ <source>Software Keyboard</source>
+ <translation>Віртуальна клавіатура</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_software_keyboard.ui" line="199"/>
+ <source>Enter Text</source>
+ <translation>Введіть текст</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_software_keyboard.ui" line="479"/>
+ <source>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:26pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:&apos;MS Shell Dlg 2&apos;; font-size:26pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_software_keyboard.cpp" line="403"/>
+ <location filename="../../src/yuzu/applets/qt_software_keyboard.cpp" line="413"/>
+ <source>OK</source>
+ <translation>ОК</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/applets/qt_software_keyboard.cpp" line="413"/>
+ <source>Cancel</source>
+ <translation>Скасувати</translation>
+ </message>
+</context>
+<context>
+ <name>SequenceDialog</name>
+ <message>
+ <location filename="../../src/yuzu/util/sequence_dialog/sequence_dialog.cpp" line="10"/>
+ <source>Enter a hotkey</source>
+ <translation>Введіть комбінацію</translation>
+ </message>
+</context>
+<context>
+ <name>WaitTreeCallstack</name>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="147"/>
+ <source>Call stack</source>
+ <translation>Стек викликів</translation>
+ </message>
+</context>
+<context>
+ <name>WaitTreeMutexInfo</name>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="126"/>
+ <source>waiting for mutex 0x%1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="133"/>
+ <source>has waiters: %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="135"/>
+ <source>owner handle: 0x%1</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>WaitTreeObjectList</name>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="228"/>
+ <source>waiting for all objects</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="229"/>
+ <source>waiting for one of the following objects</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>WaitTreeSynchronizationObject</name>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="185"/>
+ <source>[%1] %2 %3</source>
+ <translation>[%1] %2 %3</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="212"/>
+ <source>waited by no thread</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>WaitTreeThread</name>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="250"/>
+ <source>runnable</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="252"/>
+ <source>paused</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="258"/>
+ <source>sleeping</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="261"/>
+ <source>waiting for IPC reply</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="264"/>
+ <source>waiting for objects</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="267"/>
+ <source>waiting for condition variable</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="270"/>
+ <source>waiting for address arbiter</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="273"/>
+ <source>waiting for suspend resume</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="276"/>
+ <source>waiting</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="281"/>
+ <source>initialized</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="284"/>
+ <source>terminated</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="287"/>
+ <source>unknown</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="292"/>
+ <source> PC = 0x%1 LR = 0x%2</source>
+ <translation> PC = 0x%1 LR = 0x%2</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="342"/>
+ <source>ideal</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="345"/>
+ <source>core %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="349"/>
+ <source>processor = %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="351"/>
+ <source>ideal core = %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="353"/>
+ <source>affinity mask = %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="354"/>
+ <source>thread id = %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="355"/>
+ <source>priority = %1(current) / %2(normal)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="359"/>
+ <source>last running ticks = %1</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="367"/>
+ <source>not waiting for mutex</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>WaitTreeThreadList</name>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="391"/>
+ <source>waited by thread</source>
+ <translation type="unfinished"/>
+ </message>
+</context>
+<context>
+ <name>WaitTreeWidget</name>
+ <message>
+ <location filename="../../src/yuzu/debugger/wait_tree.cpp" line="465"/>
+ <source>&amp;Wait Tree</source>
+ <translation>[&amp;W] Дерево очікування</translation>
+ </message>
+</context>
+</TS> \ No newline at end of file
diff --git a/dist/languages/vi.ts b/dist/languages/vi.ts
index 6570ab683..181e320aa 100644
--- a/dist/languages/vi.ts
+++ b/dist/languages/vi.ts
@@ -89,78 +89,78 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -733,200 +733,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Cho phép bật GDB sơ khai</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Cổng:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Báo cáo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Bộ lọc báo cáo chung</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Mở vị trí sổ ghi chép</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Khi tích vào, dung lượng tối đa cho file log chuyển từ 100 MB lên 1 GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Xâu lệnh</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Đồ hoạ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Kích hoạt chế độ gỡ lỗi đồ hoạ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Không dùng Macro JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Vá lỗi</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
- <source>Enable FS Access Log</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Nâng Cao</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Bật Vá Lỗi CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Sẽ tự động thiết lập lại khi tắt yuzu.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1545,37 +1580,47 @@ This would ban both their forum username and their IP address.</source>
<translation>Tăng Tốc Thời Gian GPU (Hack)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Bộ lọc góc nghiêng:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Mặc định</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2067,7 +2112,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Cần trái</translation>
</message>
@@ -2161,14 +2206,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2187,7 +2232,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Cộng</translation>
</message>
@@ -2200,15 +2245,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2265,231 +2310,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Cần phải</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Bỏ trống</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[không đặt]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
+ <source>Invert button</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
- <source>Invert button</source>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Chọn một giá trị giữa 0% và 100%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Thiết lập Cần Điều Khiển</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Sau khi bấm OK, di chuyển cần sang ngang, rồi sau đó sang dọc.
Nếu muốn đảo ngược hướng cần điều khiển, di chuyển cần sang dọc trước, rồi sang ngang.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Tay cầm Pro Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Joycon đôi</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Joycon Trái</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Joycon Phải</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Cầm tay</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>Tay cầm GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Bắt đầu / Tạm ngưng</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Lắc!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[Chờ]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Hồ sơ mới</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Nhập tên hồ sơ:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Tạo Hồ Sơ Phím</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>Tên hồ sơ không hợp lệ!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Quá trình tạo hồ sơ phím &quot;%1&quot; thất bại</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Xóa Hồ Sơ Phím</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Quá trình xóa hồ sơ phím &quot;%1&quot; thất bại</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Nạp Hồ Sơ Phím</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Quá trình nạp hồ sơ phím &quot;%1&quot; thất bại</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Lưu Hồ Sơ Phím</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Quá trình lưu hồ sơ phím &quot;%1&quot; thất bại</translation>
</message>
@@ -2744,42 +2794,42 @@ Nếu muốn đảo ngược hướng cần điều khiển, di chuyển cần s
<translation>Nhà Phát Hành</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Bổ Sung</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Chung</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Hệ thống</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Đồ hoạ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Đồ Họa Nâng Cao</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Âm thanh</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Thuộc tính</translation>
</message>
@@ -3491,47 +3541,47 @@ Nếu muốn đảo ngược hướng cần điều khiển, di chuyển cần s
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Đường dẫn</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3940,7 +3990,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Xác nhận</translation>
</message>
@@ -4027,7 +4077,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation type="unfinished"/>
</message>
@@ -4042,17 +4092,36 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Xác nhận không thành công</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Xác nhận không thành công</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation type="unfinished"/>
</message>
@@ -4121,12 +4190,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation type="unfinished"/>
</message>
@@ -4134,908 +4203,888 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Dữ liệu ẩn danh được thu thập&lt;/a&gt;để hỗ trợ cải thiện yuzu. &lt;br/&gt;&lt;br/&gt;Bạn có muốn chia sẽ dữ liệu sử dụng cho chúng tôi?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Viễn trắc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Tốc độ giả lập hiện tại. Giá trị cao hơn hoặc thấp hơn 100% chỉ ra giả lập sẽ chạy nhanh hơn hoặc chậm hơn trên máy Switch</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Có bao nhiêu khung hình trên mỗi giây mà trò chơi đang hiển thị. Điều này sẽ thay đổi từ giữa các trò chơi và các khung cảnh khác nhau.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Thời gian mà giả lập lấy từ khung hình Switch, sẽ không kể đến giới hạn khung hình hoặc v-sync. Đối với tốc độ tối đa mà giả lập nhận được nhiều nhất là ở độ khoảng 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Tạm dừng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Chú ý định dạng trò chơi đã lỗi thời</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Bạn đang sử dụng định dạng danh mục ROM giải mã cho trò chơi này, và đó là một định dạng lỗi thời đã được thay thế bởi những thứ khác như NCA, NAX, XCI, hoặc NSP. Danh mục ROM giải mã có thể thiếu các icon, metadata, và hỗ trợ cập nhật.&lt;br&gt;&lt;br&gt;Để hiểu thêm về các định dạng khác nhau của Switch mà yuzu hỗ trợ, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;vui lòng kiểm tra trên wiki của chúng tôi&lt;/a&gt;. Thông báo này sẽ không hiển thị lại lần sau.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Lỗi xảy ra khi nạp ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>Định dạng ROM này không hỗ trợ.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Đã xảy ra lỗi khi khởi tạo lõi đồ hoạ.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Đã xảy ra lỗi không xác định. Hãy kiểm tra phần báo cáo để biết thêm chi tiết.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Xảy ra lỗi khi mở %1 thư mục</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Thư mục này không tồn tại!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Cập nhật</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>Khai thác RomFS không thành công!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Đã xảy ra lỗi khi sao chép tệp tin RomFS hoặc người dùng đã hủy bỏ hoạt động này.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Sườn</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Chọn chế độ kết xuất RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Vui lòng chọn cách mà bạn muốn RomFS kết xuất.&lt;br&gt;Chế độ Đầy Đủ sẽ sao chép toàn bộ tệp tin vào một danh mục mới trong khi &lt;br&gt;chế độ Sườn chỉ tạo kết cấu danh mục.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Khai thác RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Hủy bỏ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Khai thác RomFS thành công!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>Các hoạt động đã hoàn tất thành công.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Chọn danh mục</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Thuộc tính</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Không thể tải thuộc tính của trò chơi.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Thực thi Switch (%1);;Tất cả tệp tin (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Nạp tệp tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Mở danh mục ROM đã trích xuất</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Danh mục đã chọn không hợp lệ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Danh mục mà bạn đã chọn không có chứa tệp tin &apos;main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Những tệp tin Switch cài được (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Đang cài đặt tệp tin &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Ứng dụng hệ thống</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Hệ thống lưu trữ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Cập nhật hệ thống ứng dụng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Gói phần mềm hệ thống (Loại A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Gói phần mềm (Loại B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Trò chơi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Cập nhật trò chơi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>Nội dung trò chơi có thể tải xuống</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Tiêu đề Delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Chọn cách cài đặt NCA...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Vui lòng chọn loại tiêu đề mà bạn muốn cài đặt NCA này:
(Trong hầu hết trường hợp, chọn mặc định &apos;Game&apos; là tốt nhất.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Cài đặt đã không thành công</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Loại tiêu đề NCA mà bạn chọn nó không hợp lệ.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Không tìm thấy tệp tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Không tìm thấy tệp tin &quot;%1&quot;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Thiếu tài khoản yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Để gửi trường hợp thử nghiệm trò chơi tương thích, bạn phải liên kết tài khoản yuzu.&lt;br&gt;&lt;br/&gt;Để liên kết tải khoản yuzu của bạn, hãy đến Giả lập &amp;gt; Thiết lập &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Tệp tin Amiibo (%1);; Tất cả tệp tin (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Nạp dữ liệu Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Xảy ra lỗi khi mở dữ liệu tệp tin Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Không thể mở tệp tin Amiibo &quot;%1&quot; để đọc.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Xảy ra lỗi khi đọc dữ liệu tệp tin Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Hoàn toàn không thể đọc được dữ liệu Amiibo. Dự kiến byte sẽ đọc là %1, nhưng byte chỉ có thể đọc là %2.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Xảy ra lỗi khi nạp dữ liệu Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Không thể nạp dữ liệu Amiibo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Chụp ảnh màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>Hình ảnh PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Bắt đầu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Tốc độ: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Tốc độ: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Trò chơi: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Khung hình: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>Trò chơi bạn muốn chạy yêu cầu một số tệp tin được sao chép từ thiết từ máy Switch của bạn trước khi bắt đầu chơi.&lt;br/&gt;&lt;br/&gt;Để biết thêm thông tin về cách sao chép những tệp tin đó, vui lòng tham khảo những wiki sau: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Sao chép dữ liệu hệ thống và font dùng chung từ máy Switch&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Bạn có muốn trở về danh sách trò chơi? Nếu bạn vẫn tiếp tục thì trò chơi có thể gặp sự cố, dữ liệu lưu tiến trình có thể bị lỗi, hoặc bạn sẽ gặp những lỗi khác.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Không tìm thấy tệp tin hệ thống</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Bị thiếu tệp tin hệ thống</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu không thể tìm thấy vị trí font dùng chung của Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Không tìm thấy font dùng chung</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Bị thiếu font dùng chung</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Lỗi nghiêm trọng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu đã xảy ra lỗi nghiêm trọng, vui lòng kiểm tra sổ ghi chép để biết thêm chi tiết. Để biết thêm thông tin về cách truy cập sổ ghi chép, vui lòng xem trang sau: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Làm sao để tải tệp tin sổ ghi chép lên&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Bạn có muốn trở về danh sách game? Tiếp tục có thể khiến giả lập gặp sự cố, gây hỏng dữ liệu đã lưu, hoặc gây các lỗi khác.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Xác nhận mã khóa Rederivation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5052,37 +5101,37 @@ và phải tạo ra một bản sao lưu lại.
Điều này sẽ xóa mã khóa tự động tạo trên tệp tin của bạn và chạy lại mô-đun chiết xuất mã khoá.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5091,39 +5140,39 @@ on your system&apos;s performance.</source>
hệ thống của bạn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Mã khóa xuất phát</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Chọn thư mục để sao chép RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Vui lòng chọn RomFS mà bạn muốn chiết xuất.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Bạn có chắc chắn muốn đóng yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Bạn có chắc rằng muốn dừng giả lập? Bất kì tiến trình nào chưa được lưu sẽ bị mất.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5502,12 +5551,12 @@ Screen.</source>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5516,11 +5565,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5542,112 +5592,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Chụp ảnh màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Toàn màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Nạp tệp tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5761,42 +5810,42 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Người chơi</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation type="unfinished"/>
</message>
@@ -6123,7 +6172,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Đã kết nối</translation>
</message>
@@ -6145,7 +6194,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation type="unfinished"/>
</message>
@@ -6249,22 +6298,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6272,7 +6338,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
@@ -6327,7 +6393,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation type="unfinished"/>
</message>
@@ -6382,7 +6448,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[chưa đặt nút]</translation>
</message>
@@ -6397,10 +6463,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Trục %1%2</translation>
</message>
@@ -6414,9 +6480,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[không xác định]</translation>
</message>
@@ -6581,15 +6647,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation type="unfinished"/>
</message>
@@ -6597,35 +6663,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[không sử dụng]</translation>
</message>
@@ -6666,7 +6732,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation type="unfinished"/>
</message>
diff --git a/dist/languages/vi_VN.ts b/dist/languages/vi_VN.ts
index 88c97201f..a35d60004 100644
--- a/dist/languages/vi_VN.ts
+++ b/dist/languages/vi_VN.ts
@@ -89,78 +89,78 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -733,200 +733,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>Cho phép bật GDB sơ khai</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>Cổng:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>Sổ ghi chép</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>Bộ lọc sổ ghi chép</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>Mở vị trí sổ ghi chép</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>Khi tích vào, dung lượng tối đa cho file log chuyển từ 100 MB lên 1 GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>Chuỗi đối số</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>Đồ hoạ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>Kích hoạt chế độ gỡ lỗi đồ hoạ</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>Không dùng Macro JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>Vá lỗi</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
- <source>Enable FS Access Log</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>Nâng Cao</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>Bật Vá Lỗi CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**Sẽ tự động thiết lập lại khi tắt yuzu.</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation type="unfinished"/>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1545,37 +1580,47 @@ This would ban both their forum username and their IP address.</source>
<translation>Tăng Tốc Thời Gian GPU (Hack)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>Bộ lọc góc nghiêng:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>Mặc định</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2067,7 +2112,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>Cần trái</translation>
</message>
@@ -2161,14 +2206,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2187,7 +2232,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>Cộng</translation>
</message>
@@ -2200,15 +2245,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2265,231 +2310,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>Cần phải</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>Bỏ trống</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[không đặt]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
+ <source>Invert button</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
- <source>Invert button</source>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>Chọn một giá trị giữa 0% và 100%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>Thiết lập Cần Điều Khiển</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>Sau khi bấm OK, di chuyển cần sang ngang, rồi sau đó sang dọc.
Nếu muốn đảo ngược hướng cần điều khiển, di chuyển cần sang dọc trước, rồi sang ngang.</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Tay cầm Pro Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>Joycon đôi</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>Joycon Trái</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>Joycon Phải</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>Cầm tay</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>Tay cầm GameCube</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>Bắt đầu / Tạm ngưng</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C-Stick</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>Lắc!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[Chờ]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>Hồ sơ mới</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>Nhập tên hồ sơ:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>Tạo Hồ Sơ Phím</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>Tên hồ sơ không hợp lệ!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>Quá trình tạo hồ sơ phím &quot;%1&quot; thất bại</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>Xóa Hồ Sơ Phím</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>Quá trình xóa hồ sơ phím &quot;%1&quot; thất bại</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>Nạp Hồ Sơ Phím</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>Quá trình nạp hồ sơ phím &quot;%1&quot; thất bại</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>Lưu Hồ Sơ Phím</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>Quá trình lưu hồ sơ phím &quot;%1&quot; thất bại</translation>
</message>
@@ -2744,42 +2794,42 @@ Nếu muốn đảo ngược hướng cần điều khiển, di chuyển cần s
<translation>Nhà Phát Hành</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>Bổ Sung</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>Tổng Quan</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>Hệ Thống</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>Đồ Họa</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>Đồ Họa Nâng Cao</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>Âm Thanh</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>Thuộc tính</translation>
</message>
@@ -3491,47 +3541,47 @@ Nếu muốn đảo ngược hướng cần điều khiển, di chuyển cần s
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>Đường dẫn</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3940,7 +3990,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>Xác nhận</translation>
</message>
@@ -4027,7 +4077,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation type="unfinished"/>
</message>
@@ -4042,17 +4092,36 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>Xác nhận không thành công</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>Xác nhận không thành công</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation type="unfinished"/>
</message>
@@ -4121,12 +4190,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation type="unfinished"/>
</message>
@@ -4134,908 +4203,888 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Dữ liệu ẩn danh được thu thập&lt;/a&gt;để hỗ trợ cải thiện yuzu. &lt;br/&gt;&lt;br/&gt;Bạn có muốn chia sẽ dữ liệu sử dụng cho chúng tôi?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>Viễn trắc</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>Tốc độ giả lập hiện tại. Giá trị cao hơn hoặc thấp hơn 100% chỉ ra giả lập sẽ chạy nhanh hơn hoặc chậm hơn trên máy Switch</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>Có bao nhiêu khung hình trên mỗi giây mà trò chơi đang hiển thị. Điều này sẽ thay đổi từ trò chơi này đến trò chơi kia và khung cảnh này đến khung cảnh kia.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>Thời gian mà giả lập lấy từ khung hình Switch, sẽ không kể đến giới hạn khung hình hoặc v-sync. Đối với tốc độ tối đa mà giả lập nhận được nhiều nhất là ở độ khoảng 16.67 ms.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;Tạm dừng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>Chú ý định dạng trò chơi đã lỗi thời</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>Bạn đang sử dụng định dạng danh mục ROM giải mã cho trò chơi này, và đó là một định dạng lỗi thời đã được thay thế bởi những thứ khác như NCA, NAX, XCI, hoặc NSP. Danh mục ROM giải mã có thể thiếu biểu tượng, metadata, và hỗ trợ cập nhật.&lt;br&gt;&lt;br&gt;Để giải thích về các định dạng khác nhau của Switch mà yuzu hỗ trợ, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;vui lòng kiểm tra trên wiki của chúng tôi&lt;/a&gt;. Thông báo này sẽ không hiển thị lại lần sau.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>Xảy ra lỗi khi đang nạp ROM!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>Định dạng ROM này không hỗ trợ.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>Đã xảy ra lỗi khi khởi tạo lõi video.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>Đã xảy ra lỗi không xác định. Vui lòng kiểm tra sổ ghi chép để biết thêm chi tiết.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>Xảy ra lỗi khi mở %1 thư mục</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>Thư mục này không tồn tại!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>Cập nhật</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>Khai thác RomFS không thành công!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>Đã xảy ra lỗi khi sao chép tệp tin RomFS hoặc người dùng đã hủy bỏ hoạt động này.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>Sườn</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>Chọn chế độ kết xuất RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>Vui lòng chọn RomFS mà bạn muốn kết xuất như thế nào.&lt;br&gt;Đầy đủ sẽ sao chép toàn bộ tệp tin vào một danh mục mới trong khi &lt;br&gt;bộ xương chỉ tạo kết cấu danh mục.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>Khai thác RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>Hủy bỏ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>Khai thác RomFS thành công!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>Các hoạt động đã hoàn tất thành công.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>Chọn danh mục</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>Thuộc tính</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>Thuộc tính của trò chơi không thể nạp được.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Thực thi Switch (%1);;Tất cả tệp tin (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>Nạp tệp tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>Mở danh mục ROM đã trích xuất</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>Danh mục đã chọn không hợp lệ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>Danh mục mà bạn đã chọn không có chứa tệp tin &apos;main&apos;.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>Những tệp tin Switch cài được (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>Đang cài đặt tệp tin &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>Hệ thống ứng dụng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>Hệ thống lưu trữ</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>Cập nhật hệ thống ứng dụng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>Gói phần mềm (Loại A)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>Gói phần mềm (Loại B)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>Trò chơi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>Cập nhật trò chơi</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>Nội dung trò chơi có thể tải xuống</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Tiêu đề Delta</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>Chọn loại NCA để cài đặt...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>Vui lòng chọn loại tiêu đề mà bạn muốn cài đặt NCA này:
(Trong hầu hết trường hợp, chọn mặc định &apos;Game&apos; là tốt nhất.)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>Cài đặt đã không thành công</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>Loại tiêu đề NCA mà bạn chọn nó không hợp lệ.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>Không tìm thấy tệp tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>Không tìm thấy &quot;%1&quot; tệp tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>OK</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>Thiếu tài khoản yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>Để gửi trường hợp thử nghiệm trò chơi tương thích, bạn phải liên kết tài khoản yuzu.&lt;br&gt;&lt;br/&gt;Để liên kết tải khoản yuzu của bạn, hãy đến Giả lập &amp;gt; Thiết lập &amp;gt; Web.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Tệp tin Amiibo (%1);; Tất cả tệp tin (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>Nạp dữ liệu Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>Xảy ra lỗi khi mở dữ liệu tệp tin Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>Không thể mở tệp tin Amiibo &quot;%1&quot; để đọc.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>Xảy ra lỗi khi đọc dữ liệu tệp tin Amiibo</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>Hoàn toàn không thể đọc được dữ liệu Amiibo. Dự kiến byte sẽ đọc là %1, nhưng byte chỉ có thể đọc là %2.</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>Xảy ra lỗi khi nạp dữ liệu Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>Không thể nạp dữ liệu Amiibo.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>Chụp ảnh màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>Hình ảnh PNG (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>&amp;Bắt đầu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation type="unfinished"/>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation type="unfinished"><numerusform></numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>Tốc độ: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>Tốc độ: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>Trò chơi: %1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>Khung hình: %1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>Trò chơi bạn muốn chạy yêu cầu một số tệp tin được sao chép từ thiết từ máy Switch của bạn trước khi bắt đầu chơi.&lt;br/&gt;&lt;br/&gt;Để biết thêm thông tin về cách sao chép những tệp tin đó, vui lòng tham khảo những wiki sau: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Sao chép dữ liệu hệ thống và font dùng chung từ máy Switch&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Bạn có muốn trở về danh sách trò chơi? Nếu bạn vẫn tiếp tục thì trò chơi có thể gặp sự cố, dữ liệu lưu tiến trình có thể bị lỗi, hoặc bạn sẽ gặp những lỗi khác.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>Không tìm thấy tệp tin hệ thống</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>Bị thiếu tệp tin hệ thống</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>yuzu không thể tìm thấy vị trí font dùng chung của Switch. %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>Không tìm thấy font dùng chung</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>Bị thiếu font dùng chung</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>Lỗi nghiêm trọng</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu đã xảy ra lỗi nghiêm trọng, vui lòng kiểm tra sổ ghi chép để biết thêm chi tiết. Để biết thêm thông tin về cách truy cập sổ ghi chép, vui lòng xem trang sau: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;Làm sao để tải tệp tin sổ ghi chép lên&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Bạn có muốn trở về danh sách game? Tiếp tục có thể khiến giả lập gặp sự cố, gây hỏng dữ liệu đã lưu, hoặc gây các lỗi khác.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>Xác nhận mã khóa Rederivation</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5052,37 +5101,37 @@ và phải tạo ra một bản sao lưu lại.
Điều này sẽ xóa mã khóa tự động tạo trên tệp tin của bạn và chạy lại mô-đun mã khóa derivation.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5091,39 +5140,39 @@ on your system&apos;s performance.</source>
vào hiệu suất hệ thống của bạn.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>Mã khóa xuất phát</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>Chọn thư mục để sao chép RomFS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>Vui lòng chọn RomFS mà bạn muốn sao chép.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>Bạn có chắc chắn muốn đóng yuzu?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>Bạn có chắc rằng muốn dừng giả lập? Bất kì tiến trình nào chưa được lưu sẽ bị mất.</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5500,12 +5549,12 @@ Screen.</source>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation type="unfinished"/>
@@ -5514,11 +5563,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation type="unfinished"/>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5540,112 +5590,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>Chụp ảnh màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>Toàn màn hình</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>Nạp tệp tin</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation type="unfinished"/>
</message>
@@ -5759,42 +5808,42 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>Người chơi</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation type="unfinished"/>
</message>
@@ -6121,7 +6170,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>Đã kết nối</translation>
</message>
@@ -6143,7 +6192,7 @@ Debug Message: </source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation type="unfinished"/>
</message>
@@ -6247,22 +6296,39 @@ They may have left the room.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation type="unfinished"/>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation type="unfinished"/>
</message>
@@ -6270,7 +6336,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation type="unfinished"/>
</message>
@@ -6325,7 +6391,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation type="unfinished"/>
</message>
@@ -6380,7 +6446,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[chưa đặt nút]</translation>
</message>
@@ -6395,10 +6461,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Trục %1%2</translation>
</message>
@@ -6412,9 +6478,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[không xác định]</translation>
</message>
@@ -6579,15 +6645,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation type="unfinished"/>
</message>
@@ -6595,35 +6661,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation type="unfinished"/>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[không sử dụng]</translation>
</message>
@@ -6664,7 +6730,7 @@ p, li { white-space: pre-wrap; }
<translation type="unfinished"/>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation type="unfinished"/>
</message>
diff --git a/dist/languages/zh_CN.ts b/dist/languages/zh_CN.ts
index a70052b5c..f8137e297 100644
--- a/dist/languages/zh_CN.ts
+++ b/dist/languages/zh_CN.ts
@@ -95,78 +95,78 @@ p, li { white-space: pre-wrap; }
<translation>发送消息</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation>成员</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation>%1 已加入</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation>%1 已离开</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation>%1 已被踢出房间</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation>%1 已被封禁</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation>%1 已被解封</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation>查看个人资料</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation>屏蔽玩家</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
- <translation>当你屏蔽玩家后,你将无法收到他们的聊天消息。&lt;br&gt;&lt;br&gt;您确定要屏蔽 %1 吗?</translation>
+ <translation>屏蔽玩家后,你将无法收到他们的聊天消息。&lt;br&gt;&lt;br&gt;您确定要屏蔽 %1 吗?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation>踢出房间</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation>封禁</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation>踢出玩家</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation>您确定要将 %1 &lt;b&gt;踢出房间&lt;/b&gt;吗?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation>封禁玩家</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -768,200 +768,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation>调试器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>开启 GDB 调试</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>端口:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>日志</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>全局日志过滤器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>显示日志窗口</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>打开日志位置</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>选中此项后,日志文件的最大大小从 100MB 增加到 1GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>启用扩展的日志记录**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>自制游戏</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>参数字符串</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>图形</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>启用时,图形 API 将进入较慢的调试模式。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>启用图形调试</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>启用后,yuzu 将会保存 Nsight Aftermath 格式的崩溃转储文件</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>启用 Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation>启用时,将从磁盘着色器缓存或游戏中转储所有的着色器文件。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation>转储着色器文件</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation>选中后,将转储 GPU 的所有宏程序</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation>转储 Maxwell 宏</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>启用时,将禁用宏即时编译器。这会降低游戏运行速度。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>禁用宏 JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>选中时,yuzu 将记录有关已编译着色器缓存的统计信息。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>启用着色器反馈</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>启用后,yuzu 在执行着色器时,不会修改循环结构的条件判断</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>禁用循环体安全检查</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>调试选项</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
- <source>Enable FS Access Log</source>
- <translation>启用文件系统访问记录</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>启用详细报告服务**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
- <translation>将音频命令转储至控制台**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
+ <translation>启用文件系统访问记录</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>启用此选项会将最新的音频命令列表输出到控制台。只影响使用音频渲染器的游戏。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>启用详细报告服务**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
+ <translation>将音频命令转储至控制台**</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation>微型故障转储</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>高级选项</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Kiosk (Quest) 模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>启用 CPU 模拟调试</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>启用调试</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>启用自动函数打桩(Auto-Stub)**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation>启用其他类型的控制器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>禁用 Web 应用程序</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation>允许 yuzu 在启动时检查 Vulkan 环境是否正常工作。如果是其他程序导致 yuzu 出现此问题,请禁用此选项。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation>启动时进行 Vulkan 检测</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**该选项将在 yuzu 关闭时自动重置。</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation>需要重启</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation>重启 yuzu 后才能应用此设置。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation>Web 应用程序未编译</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation>微型转储未编译</translation>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1580,37 +1615,47 @@ This would ban both their forum username and their IP address.</source>
<translation>启用快速 GPU 时钟 (不稳定)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation>启用悲观缓冲区刷新。此选项将强制刷新未修改的缓冲区,可能会降低性能。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation>启用悲观缓冲区刷新 (不稳定)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>各向异性过滤:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>自动</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>系统默认</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2102,7 +2147,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>左摇杆</translation>
</message>
@@ -2196,14 +2241,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2222,7 +2267,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>+</translation>
</message>
@@ -2235,15 +2280,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2300,231 +2345,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>右摇杆</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>清除</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[未设置]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>切换按键</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>反转按钮</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>切换按键</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>体感方向倒置</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>阈值设定</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>选择一个介于 0% 和 100% 之间的值</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation>切换轴</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation>陀螺仪阈值设定</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>映射摇杆</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>在按下确定后,首先水平移动你的手柄,然后垂直移动它。
如果要使体感方向倒置,首先垂直移动你的手柄,然后水平移动它。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation>中心轴</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>摇杆死区:%1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>摇杆灵敏度:%1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Pro Controller</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>双 Joycons 手柄</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>左 Joycon 手柄</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>右 Joycon 手柄</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>掌机模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>GameCube 控制器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>精灵球 PLUS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>NES 控制器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>SNES 控制器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>N64 控制器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>世嘉创世纪</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>开始 / 暂停</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>控制摇杆</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C 摇杆</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>摇动!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[等待中]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>保存自定义设置</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>输入配置文件名称:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>新建输入配置文件</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>输入的配置文件名称无效!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>新建输入配置文件 &quot;%1&quot; 失败</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>删除输入配置文件</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>删除输入配置文件 &quot;%1&quot; 失败</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>加载输入配置文件</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>加载输入配置文件 &quot;%1&quot; 失败</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>保存输入配置文件</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>保存输入配置文件 &quot;%1&quot; 失败</translation>
</message>
@@ -2779,42 +2829,42 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation>开发商</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>附加项</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>通用</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>系统</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>图形</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>高级图形</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>声音</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>属性</translation>
</message>
@@ -3526,47 +3576,47 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;通过读取与 TAS-nx 脚本具有相同格式的脚本来读取控制器的输入。&lt;br/&gt;有关详细信息,请参阅 yuzu 官方网站的&lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;帮助页面&lt;/span&gt;&lt;/a&gt;。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>要确认是哪些热键控制播放/录制,请参阅热键设置。(设置—&gt;通用—&gt;热键)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>警告:这是一个实验性功能。&lt;br/&gt;由于暂不完善的同步方式,可能无法完整地进行回放。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>设置</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>启用 TAS 功能</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>循环脚本</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>遇到载入画面时暂停执行</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>脚本目录</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>路径</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3976,7 +4026,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>验证</translation>
</message>
@@ -4003,7 +4053,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="118"/>
<source>Web Service configuration can only be changed when a public room isn&apos;t being hosted.</source>
- <translation>公共房间未被开放时,才能更改网络服务设置。</translation>
+ <translation>公共房间未被创建时,才能更改网络服务设置。</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="128"/>
@@ -4063,7 +4113,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>未指定</translation>
</message>
@@ -4078,17 +4128,36 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>令牌未被验证。您对用户名和令牌的更改尚未保存。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation>令牌未验证,请在保存配置前先进行验证。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>验证中...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation>已验证</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>验证失败</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>验证失败</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>验证失败。请检查您输入的令牌是否正确,并且确保您的互联网连接正常。</translation>
</message>
@@ -4157,12 +4226,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation>连接中</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation>连接</translation>
</message>
@@ -4170,913 +4239,893 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;我们收集匿名数据&lt;/a&gt;来帮助改进 yuzu 。&lt;br/&gt;&lt;br/&gt;您愿意和我们分享您的使用数据吗?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>使用数据共享</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation>检测到 Vulkan 的安装已损坏</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Vulkan 初始化失败。&lt;br&gt;&lt;br&gt;点击&lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;这里&lt;/a&gt;获取此问题的相关信息。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>正在加载 Web 应用程序...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>禁用 Web 应用程序</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>禁用 Web 应用程序可能会发生未知的行为,且只能在《超级马里奥 3D 全明星》中使用。您确定要禁用 Web 应用程序吗?
(您可以在调试选项中重新启用它。)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>当前正在构建的着色器数量</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>当前选定的分辨率缩放比例。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>当前的模拟速度。高于或低于 100% 的值表示模拟正在运行得比实际 Switch 更快或更慢。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>游戏当前运行的帧率。这将因游戏和场景的不同而有所变化。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>在不计算速度限制和垂直同步的情况下,模拟一个 Switch 帧的实际时间。若要进行全速模拟,这个数值不应超过 16.67 毫秒。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>清除最近文件 (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>继续 (&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>暂停 (&amp;P)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>yuzu 正在运行中</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>过时游戏格式警告</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>目前使用的游戏为解体的 ROM 目录格式,这是一种过时的格式,已被其他格式替代,如 NCA,NAX,XCI 或 NSP。解体的 ROM 目录缺少图标、元数据和更新支持。&lt;br&gt;&lt;br&gt;有关 yuzu 支持的各种 Switch 格式的说明,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;请查看我们的 wiki&lt;/a&gt;。此消息将不会再次出现。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>加载 ROM 时出错!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>该 ROM 格式不受支持。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>在初始化视频核心时发生错误。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu 在运行视频核心时发生错误。这可能是由 GPU 驱动程序过旧造成的。有关详细信息,请参阅日志文件。关于日志文件的更多信息,请参考以下页面:&lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;如何上传日志文件&lt;/a&gt;。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>加载 ROM 时出错! %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;请参考&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu 快速导航&lt;/a&gt;以获取相关文件。&lt;br&gt;您可以参考 yuzu 的 wiki 页面&lt;/a&gt;或 Discord 社区&lt;/a&gt;以获得帮助。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>发生了未知错误。请查看日志了解详情。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>保存数据</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>Mod 数据</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>打开 %1 文件夹时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>文件夹不存在!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>打开可转移着色器缓存时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>为该游戏创建着色器缓存目录时失败。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>目录</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>游戏更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>删除项目</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>删除已安装的游戏 %1 ?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>删除成功</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>成功删除已安装的游戏。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>删除 %1 时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>该游戏未安装于 NAND 中,无法删除。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>成功删除已安装的游戏更新。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>这个游戏没有任何已安装的更新。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>这个游戏没有任何已安装的 DLC 。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>成功删除游戏 %1 安装的 DLC 。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>删除 OpenGL 模式的着色器缓存?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>删除 Vulkan 模式的着色器缓存?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>删除所有的着色器缓存?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>移除自定义游戏设置?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>删除文件</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>删除着色器缓存时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>这个游戏的着色器缓存不存在。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>成功删除着色器缓存。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>删除着色器缓存失败。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>删除着色器缓存时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>着色器缓存删除成功。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>删除着色器缓存目录失败。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>移除自定义游戏设置时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>这个游戏的自定义设置不存在。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>成功移除自定义游戏设置。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>移除自定义游戏设置失败。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS 提取失败!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>复制 RomFS 文件时出错,或用户取消了操作。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>完整</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>框架</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>选择 RomFS 转储模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>请选择希望 RomFS 转储的方式。&lt;br&gt;“Full” 会将所有文件复制到新目录中,而&lt;br&gt;“Skeleton” 只会创建目录结构。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>%1 没有足够的空间用于提取 RomFS。请保持足够的空间或于模拟—&gt;设置—&gt;系统—&gt;文件系统—&gt;转储根目录中选择一个其他目录。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>正在提取 RomFS...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>取消</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS 提取成功!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>操作成功完成。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>打开 %1 时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>选择目录</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>属性</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>无法加载该游戏的属性信息。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch 可执行文件 (%1);;所有文件 (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>加载文件</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>打开提取的 ROM 目录</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>选择的目录无效</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>选择的目录不包含 “main” 文件。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>可安装的 Switch 文件 (*.nca *.nsp *.xci);;任天堂内容档案 (*.nca);;任天堂应用包 (*.nsp);;NX 卡带镜像 (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>安装文件</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>剩余 %n 个文件</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>正在安装文件 &quot;%1&quot;...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>安装结果</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>为了避免可能存在的冲突,我们不建议将游戏本体安装到 NAND 中。
此功能仅用于安装游戏更新和 DLC 。</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>最近安装了 %n 个文件
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n 个文件被覆盖
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n 个文件安装失败
</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>系统应用</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>系统档案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>系统应用更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>固件包 (A型)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>固件包 (B型)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>游戏</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>游戏更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>游戏 DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>差量程序</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>选择 NCA 安装类型...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>请选择此 NCA 的程序类型:
(在大多数情况下,选择默认的“游戏”即可。)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>安装失败</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>选择的 NCA 程序类型无效。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>找不到文件</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>文件 &quot;%1&quot; 未找到</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>确定</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>未设置 yuzu 账户</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>要提交游戏兼容性测试用例,您必须设置您的 yuzu 帐户。&lt;br&gt;&lt;br/&gt;要设置您的 yuzu 帐户,请转到模拟 &amp;gt; 设置 &amp;gt; 网络。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>打开 URL 时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>无法打开 URL : &quot;%1&quot; 。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>TAS 录制中</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>覆盖玩家 1 的文件?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>检测到无效配置</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>掌机手柄无法在主机模式中使用。将会选择 Pro controller。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>错误</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation>当前游戏并没有在寻找 Amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation>当前的 Amiibo 已被移除。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo 文件 (%1);; 全部文件 (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>加载 Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>打开 Amiibo 数据文件时出错</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>无法打开 Amiibo 文件 %1。</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>读取 Amiibo 数据文件时出错</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>无法完全读取 Amiibo 数据。应读取 %1 个字节,但实际仅能读取 %2 个字节。</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>加载 Amiibo 数据时出错</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>无法加载 Amiibo 数据。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>捕获截图</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>PNG 图像 (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS 状态:正在运行 %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>TAS 状态:正在录制 %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAS 状态:空闲 %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>TAS 状态:无效</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>停止运行 (&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>开始 (&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>停止录制 (&amp;E)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>录制 (&amp;E)</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>正在编译 %n 个着色器文件</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>缩放比例: %1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>速度: %1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>速度: %1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>游戏: %1 FPS (未锁定)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>FPS: %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>帧延迟:%1 毫秒</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU NORMAL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU HIGH</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU EXTREME</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>GPU ERROR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation>主机模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation>掌机模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>邻近取样</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>双线性过滤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>双三线过滤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>高斯模糊</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>强制缩放</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>抗锯齿关</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>您正尝试启动的游戏需要从 Switch 转储的其他文件。&lt;br/&gt;&lt;br/&gt;有关转储这些文件的更多信息,请参阅以下 wiki 页面:&lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;。&lt;br/&gt;&lt;br/&gt;您要退出并返回至游戏列表吗?继续模拟可能会导致崩溃,存档损坏或其他错误。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>Yuzu 找不到 Switch 系统档案 %1 </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>Yuzu 找不到 Switch 系统档案: %1, %2 </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>未找到系统档案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>系统档案缺失</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>Yuzu 找不到 Swtich 共享字体 %1 </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>未找到共享字体</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>共享字体文件缺失</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>致命错误</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu 遇到了致命错误,请查看日志了解详情。有关查找日志的更多信息,请参阅以下页面:&lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;。&lt;br/&gt;&lt;br/&gt;您要退出并返回至游戏列表吗?继续模拟可能会导致崩溃,存档损坏或其他错误。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>发生致命错误</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>确认重新生成密钥</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5092,37 +5141,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
这将删除您自动生成的密钥文件并重新运行密钥生成模块。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>项目丢失</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation>- 丢失 BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - 丢失 BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation>- 丢失 PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>组件丢失</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>密钥缺失。&lt;br&gt;请查看&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu 快速导航&lt;/a&gt;以获得你的密钥、固件和游戏。&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5131,39 +5180,39 @@ on your system&apos;s performance.</source>
您的系统性能。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>生成密钥</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>选择 RomFS 转储目标</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>请选择希望转储的 RomFS。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>您确定要关闭 yuzu 吗?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>您确定要停止模拟吗?未保存的进度将会丢失。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5534,32 +5583,33 @@ Screen.</source>
<message>
<location filename="../../src/yuzu/multiplayer/host_room.ui" line="197"/>
<source>Host Room</source>
- <translation>管理房间</translation>
+ <translation>创建房间</translation>
</message>
</context>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>错误</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
- <translation>向公共大厅公开房间时失败。为了管理公开房间,您必须在模拟 -&gt; 设置 -&gt; 网络中配置有效的 yuzu 帐户。如果不想在公共大厅中公开房间,请选择“未列出”。
+ <translation>向公共大厅公开房间时失败。为了创建公开房间,您必须在模拟 -&gt; 设置 -&gt; 网络中配置有效的 yuzu 帐户。如果不想在公共大厅中公开房间,请选择“未列出”。
调试消息:</translation>
</message>
</context>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation>开启/关闭静音</translation>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5581,112 +5631,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation>主窗口</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation>调低音量</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation>调高音量</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>捕获截图</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation>更改窗口滤镜</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation>更改主机运行模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation>更改 GPU 精度</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation>继续/暂停模拟</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation>退出全屏</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation>退出 yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>全屏</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>加载文件</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation>加载/移除 Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation>重新启动模拟</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation>停止模拟</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation>TAS 录制</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation>重置 TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation>TAS 开始/停止</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation>切换搜索栏</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation>切换帧率限制</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation>切换鼠标平移</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation>切换状态栏</translation>
</message>
@@ -5788,7 +5837,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="76"/>
<source>Games I Own</source>
- <translation>游戏 I 我的</translation>
+ <translation>我拥有的游戏</translation>
</message>
<message>
<location filename="../../src/yuzu/multiplayer/lobby.ui" line="83"/>
@@ -5801,42 +5850,42 @@ Debug Message: </source>
<translation>刷新游戏大厅</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation>加入此房间需要密码</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation>密码:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation>房间名称</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation>首选游戏</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
- <translation>管理</translation>
+ <translation>房主</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
- <translation>玩家</translation>
+ <translation>玩家数</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation>刷新中</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation>刷新列表</translation>
</message>
@@ -6163,7 +6212,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>已连接</translation>
</message>
@@ -6186,7 +6235,7 @@ Debug Message: </source>
调试信息:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation>收到了新消息</translation>
</message>
@@ -6291,22 +6340,41 @@ They may have left the room.</source>
他们可能已经离开了房间。</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation>未选择网络接口。
+请于设置 -&gt; 系统 -&gt; 网络中进行相关设置。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation>游戏正在运行中</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation>不推荐游戏正在运行时加入房间,这可能会导致房间的某些功能出现异常。
+是否继续?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation>离开房间</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation>您正要关闭房间。所有的网络连接都将关闭。</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation>断开连接</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation>您正要离开房间。所有的网络连接都将关闭。</translation>
</message>
@@ -6314,7 +6382,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>错误</translation>
</message>
@@ -6373,7 +6441,7 @@ p, li { white-space: pre-wrap; }
<translation>%1 正在玩 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation>不在玩游戏</translation>
</message>
@@ -6428,7 +6496,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[未设置]</translation>
</message>
@@ -6443,10 +6511,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>轴 %1%2</translation>
</message>
@@ -6460,9 +6528,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[未知]</translation>
</message>
@@ -6627,15 +6695,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[无效]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation>%1%2Hat 控制器 %3</translation>
</message>
@@ -6643,35 +6711,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation>%1%2轴 %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation>%1%2轴 %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2体感 %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2按键 %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[未使用]</translation>
</message>
@@ -6712,7 +6780,7 @@ p, li { white-space: pre-wrap; }
<translation>额外按键</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/languages/zh_TW.ts b/dist/languages/zh_TW.ts
index ed797e876..0e976d03d 100644
--- a/dist/languages/zh_TW.ts
+++ b/dist/languages/zh_TW.ts
@@ -95,78 +95,78 @@ p, li { white-space: pre-wrap; }
<translation>发送消息</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="166"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="175"/>
<source>Members</source>
<translation>成员</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="299"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="312"/>
<source>%1 has joined</source>
<translation>%1 已加入</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="302"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="315"/>
<source>%1 has left</source>
<translation>%1 已离开</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="305"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="318"/>
<source>%1 has been kicked</source>
<translation>%1 已被踢出房间</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="308"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="321"/>
<source>%1 has been banned</source>
<translation>%1 已被封禁</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="311"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="324"/>
<source>%1 has been unbanned</source>
<translation>%1 已被解封</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="427"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
<source>View Profile</source>
<translation>查看个人资料</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="440"/>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="450"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="453"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="463"/>
<source>Block Player</source>
<translation>屏蔽玩家</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="451"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
<source>When you block a player, you will no longer receive chat messages from them.&lt;br&gt;&lt;br&gt;Are you sure you would like to block %1?</source>
<translation>当你屏蔽玩家后,你将无法收到他们的聊天消息。&lt;br&gt;&lt;br&gt;您确定要屏蔽 %1 吗?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="464"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="477"/>
<source>Kick</source>
<translation>踢出房间</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="465"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
<source>Ban</source>
<translation>封禁</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="469"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="482"/>
<source>Kick Player</source>
<translation>踢出玩家</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="470"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="483"/>
<source>Are you sure you would like to &lt;b&gt;kick&lt;/b&gt; %1?</source>
<translation>您确定要将 %1 &lt;b&gt;踢出房间&lt;/b&gt;吗?</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="478"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="491"/>
<source>Ban Player</source>
<translation>封禁玩家</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="479"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="492"/>
<source>Are you sure you would like to &lt;b&gt;kick and ban&lt;/b&gt; %1?
This would ban both their forum username and their IP address.</source>
@@ -770,200 +770,235 @@ This would ban both their forum username and their IP address.</source>
<context>
<name>ConfigureDebug</name>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="11"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="15"/>
<source>Debugger</source>
<translation>调试器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="19"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="23"/>
<source>Enable GDB Stub</source>
<translation>开启 GDB 调试</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="39"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="43"/>
<source>Port:</source>
<translation>通訊埠:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="67"/>
<source>Logging</source>
<translation>紀錄</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="71"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="75"/>
<source>Global Log Filter</source>
<translation>全域紀錄篩選器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="83"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="87"/>
<source>Show Log in Console</source>
<translation>在終端機中顯示紀錄</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="90"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="94"/>
<source>Open Log Location</source>
<translation>開啟紀錄位置</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="100"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="104"/>
<source>When checked, the max size of the log increases from 100 MB to 1 GB</source>
<translation>啟用後紀錄檔案大小上限從 100MB 增加到 1GB</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="103"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="107"/>
<source>Enable Extended Logging**</source>
<translation>啟用延伸紀錄**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="113"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="117"/>
<source>Homebrew</source>
<translation>Homebrew</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="121"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="125"/>
<source>Arguments String</source>
<translation>參數字串</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="136"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="140"/>
<source>Graphics</source>
<translation>圖形</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="145"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="149"/>
<source>When checked, the graphics API enters a slower debugging mode</source>
<translation>啟用時圖形 API 會進入較慢的偵錯模式。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="152"/>
<source>Enable Graphics Debugging</source>
<translation>啟用圖形偵錯</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="155"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="159"/>
<source>When checked, it enables Nsight Aftermath crash dumps</source>
<translation>啟用時 yuzu 將會儲存 Nsight Aftermath 格式的錯誤傾印檔案。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="158"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="162"/>
<source>Enable Nsight Aftermath</source>
<translation>啟用 Nsight Aftermath</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="168"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="172"/>
<source>When checked, it will dump all the original assembler shaders from the disk shader cache or game as found</source>
<translation>啟用時,將從磁碟著色器快娶或遊戲中轉儲所有的著色器檔案。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="171"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="175"/>
<source>Dump Game Shaders</source>
<translation>傾印遊戲著色器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="181"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="185"/>
<source>When checked, it will dump all the macro programs of the GPU</source>
<translation>选中后,将转储 GPU 的所有宏程序</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="188"/>
<source>Dump Maxwell Macros</source>
<translation>转储 Maxwell 宏</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="194"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="198"/>
<source>When checked, it disables the macro Just In Time compiler. Enabling this makes games run slower</source>
<translation>啟用時將停用 Macro Just In Time 編譯器,會使得效能降低。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="201"/>
<source>Disable Macro JIT</source>
<translation>停用 Macro JIT</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="204"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="208"/>
<source>When checked, yuzu will log statistics about the compiled pipeline cache</source>
<translation>啟用時 yuzu 將記錄有關編譯著色器快取的統計資訊。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="211"/>
<source>Enable Shader Feedback</source>
<translation>啟用著色器回饋</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="214"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="218"/>
<source>When checked, it executes shaders without loop logic changes</source>
<translation>啟用時 yuzu 在執行著色器時,不會修改循環結構的條件判斷。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="217"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="221"/>
<source>Disable Loop safety checks</source>
<translation>停用循環安全檢查</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="227"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="231"/>
<source>Debugging</source>
<translation>偵錯</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="233"/>
- <source>Enable FS Access Log</source>
- <translation>啟用檔案系統存取記錄</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="237"/>
+ <source>Enable Verbose Reporting Services**</source>
+ <translation>啟用詳細報告服務</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="240"/>
- <source>Dump Audio Commands To Console**</source>
- <translation>将音频命令转储至控制台**</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="244"/>
+ <source>Enable FS Access Log</source>
+ <translation>啟用檔案系統存取記錄</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="251"/>
<source>Enable this to output the latest generated audio command list to the console. Only affects games using the audio renderer.</source>
<translation>启用此选项会将最新的音频命令列表输出到控制台。只影响使用音频渲染器的游戏。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="250"/>
- <source>Enable Verbose Reporting Services**</source>
- <translation>啟用詳細報告服務</translation>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="254"/>
+ <source>Dump Audio Commands To Console**</source>
+ <translation>将音频命令转储至控制台**</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="261"/>
+ <source>Create Minidump After Crash</source>
+ <translation>微型故障转储</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="271"/>
<source>Advanced</source>
<translation>進階</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="266"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="277"/>
<source>Kiosk (Quest) Mode</source>
<translation>Kiosk (Quest) 模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="273"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="284"/>
<source>Enable CPU Debugging</source>
<translation>啟用 CPU 模擬偵錯</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="280"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="291"/>
<source>Enable Debug Asserts</source>
<translation>啟用偵錯</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="287"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="298"/>
<source>Enable Auto-Stub**</source>
<translation>啟用自動偵錯**</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="294"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="305"/>
<source>Enable All Controller Types</source>
<translation>启用其他控制器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="301"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="312"/>
<source>Disable Web Applet</source>
<translation>停用 Web Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_debug.ui" line="316"/>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="319"/>
+ <source>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</source>
+ <translation>允许 yuzu 在启动时检查 Vulkan 环境是否正常工作。如果是其他程序导致 yuzu 出现此问题,请禁用此选项。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="322"/>
+ <source>Perform Startup Vulkan Check</source>
+ <translation>启动时进行 Vulkan 检测</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.ui" line="337"/>
<source>**This will be reset automatically when yuzu closes.</source>
<translation>**當 yuzu 關閉時會自動重設。</translation>
</message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="35"/>
+ <source>Restart Required</source>
+ <translation>需要重启</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="36"/>
+ <source>yuzu is required to restart in order to apply this setting.</source>
+ <translation>重启 yuzu 后才能应用此设置。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="86"/>
+ <source>Web applet not compiled</source>
+ <translation>Web 应用程序未编译</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_debug.cpp" line="93"/>
+ <source>MiniDump creation not compiled</source>
+ <translation>小型转储创建未编译</translation>
+ </message>
</context>
<context>
<name>ConfigureDebugController</name>
@@ -1582,37 +1617,47 @@ This would ban both their forum username and their IP address.</source>
<translation>使用快速 GPU 時間(不穩定)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="120"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="105"/>
+ <source>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</source>
+ <translation>启用悲观缓冲区刷新。此选项将强制刷新未修改的缓冲区,可能会降低性能。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="108"/>
+ <source>Use pessimistic buffer flushes (Hack)</source>
+ <translation>启用悲观缓冲区刷新 (不稳定)</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="130"/>
<source>Anisotropic Filtering:</source>
<translation>各向異性過濾:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="128"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
<source>Automatic</source>
<translation>自動</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="133"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
<source>Default</source>
<translation>預設</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="138"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
<source>2x</source>
<translation>2x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="143"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
<source>4x</source>
<translation>4x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="148"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="158"/>
<source>8x</source>
<translation>8x</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="153"/>
+ <location filename="../../src/yuzu/configuration/configure_graphics_advanced.ui" line="163"/>
<source>16x</source>
<translation>16x</translation>
</message>
@@ -2104,7 +2149,7 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="291"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1284"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
<source>Left Stick</source>
<translation>左搖桿</translation>
</message>
@@ -2198,14 +2243,14 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1251"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1290"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1296"/>
<source>L</source>
<translation>L</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1306"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1345"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1281"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
<source>ZL</source>
<translation>ZL</translation>
</message>
@@ -2224,7 +2269,7 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1545"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1584"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1280"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1287"/>
<source>Plus</source>
<translation>+</translation>
</message>
@@ -2237,15 +2282,15 @@ This would ban both their forum username and their IP address.</source>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1698"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1737"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1283"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1290"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1297"/>
<source>R</source>
<translation>R</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1753"/>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="1792"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1282"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1289"/>
<source>ZR</source>
<translation>ZR</translation>
</message>
@@ -2302,231 +2347,236 @@ This would ban both their forum username and their IP address.</source>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_input_player.ui" line="2516"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1285"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
<source>Right Stick</source>
<translation>右搖桿</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="360"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="427"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="522"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="617"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="361"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="434"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="529"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="624"/>
<source>Clear</source>
<translation>清除</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="362"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="429"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="526"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="545"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="619"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="363"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="533"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="552"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="626"/>
<source>[not set]</source>
<translation>[未設定]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="365"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="622"/>
- <source>Toggle button</source>
- <translation>切換按鍵</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="371"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="631"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="366"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="638"/>
<source>Invert button</source>
<translation>無效按鈕</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="379"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="573"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="372"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="629"/>
+ <source>Toggle button</source>
+ <translation>切換按鍵</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="380"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="580"/>
<source>Invert axis</source>
<translation>方向反轉</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="385"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="386"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Set threshold</source>
<translation>設定閾值</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="389"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="436"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="390"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="443"/>
<source>Choose a value between 0% and 100%</source>
<translation>選擇介於 0% 和 100% 之間的值</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="432"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="402"/>
+ <source>Toggle axis</source>
+ <translation>切换轴</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="439"/>
<source>Set gyro threshold</source>
<translation>陀螺仪阈值设定</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="485"/>
<source>Map Analog Stick</source>
<translation>搖桿映射</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="479"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="486"/>
<source>After pressing OK, first move your joystick horizontally, and then vertically.
To invert the axes, first move your joystick vertically, and then horizontally.</source>
<translation>按下確定後,先水平再上下移動您的搖桿。
要反轉方向,則先上下再水平移動您的搖桿。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="547"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="554"/>
<source>Center axis</source>
<translation>中心轴</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="655"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1009"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="662"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1016"/>
<source>Deadzone: %1%</source>
<translation>無感帶:%1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="664"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1014"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="671"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1021"/>
<source>Modifier Range: %1%</source>
<translation>輕推靈敏度:%1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="690"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1039"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="697"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1046"/>
<source>Pro Controller</source>
<translation>Pro 手把</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1043"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1050"/>
<source>Dual Joycons</source>
<translation>雙 Joycon 手把</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1047"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1054"/>
<source>Left Joycon</source>
<translation>左 Joycon 手把</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1051"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1058"/>
<source>Right Joycon</source>
<translation>右 Joycon 手把</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1055"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1062"/>
<source>Handheld</source>
<translation>掌機模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1059"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1066"/>
<source>GameCube Controller</source>
<translation>GameCube 手把</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1068"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1075"/>
<source>Poke Ball Plus</source>
<translation>精靈球 PLUS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1072"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1079"/>
<source>NES Controller</source>
<translation>NES 控制器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1076"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1083"/>
<source>SNES Controller</source>
<translation>SNES 控制器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1080"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1087"/>
<source>N64 Controller</source>
<translation>N64 控制器</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1084"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1091"/>
<source>Sega Genesis</source>
<translation>Mega Drive</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1288"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1295"/>
<source>Start / Pause</source>
<translation>開始 / 暫停</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1291"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1298"/>
<source>Z</source>
<translation>Z</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1292"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1299"/>
<source>Control Stick</source>
<translation>控制搖桿</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1293"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1300"/>
<source>C-Stick</source>
<translation>C 搖桿</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1394"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1401"/>
<source>Shake!</source>
<translation>搖動!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1396"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1403"/>
<source>[waiting]</source>
<translation>[等待中]</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>New Profile</source>
<translation>新增設定檔</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1478"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1485"/>
<source>Enter a profile name:</source>
<translation>輸入設定檔名稱:</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1486"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1493"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1501"/>
<source>Create Input Profile</source>
<translation>建立輸入設定檔</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1487"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1494"/>
<source>The given profile name is not valid!</source>
<translation>輸入的設定檔名稱無效!</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1495"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1502"/>
<source>Failed to create the input profile &quot;%1&quot;</source>
<translation>建立輸入設定檔「%1」失敗</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1515"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1522"/>
<source>Delete Input Profile</source>
<translation>刪除輸入設定檔</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1516"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1523"/>
<source>Failed to delete the input profile &quot;%1&quot;</source>
<translation>刪除輸入設定檔「%1」失敗</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1538"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1545"/>
<source>Load Input Profile</source>
<translation>載入輸入設定檔</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1539"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1546"/>
<source>Failed to load the input profile &quot;%1&quot;</source>
<translation>載入輸入設定檔「%1」失敗</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1558"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1565"/>
<source>Save Input Profile</source>
<translation>儲存輸入設定檔</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1559"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="1566"/>
<source>Failed to save the input profile &quot;%1&quot;</source>
<translation>儲存輸入設定檔「%1」失敗</translation>
</message>
@@ -2781,42 +2831,42 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation>出版商</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="57"/>
<source>Add-Ons</source>
<translation>延伸模組</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="58"/>
<source>General</source>
<translation>一般</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="59"/>
<source>System</source>
<translation>系統</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="60"/>
<source>CPU</source>
<translation>CPU</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="61"/>
<source>Graphics</source>
<translation>圖形</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="62"/>
<source>Adv. Graphics</source>
<translation>進階圖形</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="63"/>
<source>Audio</source>
<translation>音訊</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="67"/>
+ <location filename="../../src/yuzu/configuration/configure_per_game.cpp" line="66"/>
<source>Properties</source>
<translation>屬性</translation>
</message>
@@ -3528,47 +3578,47 @@ To invert the axes, first move your joystick vertically, and then horizontally.<
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;通過讀取與 TAS-nx 腳本具有相同格式的腳本來讀取控制器的輸入。&lt;br/&gt;有關詳細資訊,請參閱 yuzu 官方網站的&lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;說明網頁&lt;/span&gt;&lt;/a&gt;。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="24"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="27"/>
<source>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</source>
<translation>要確認是哪些快速鍵控制播放/錄製,請參閱快速鍵設定。(設定 &gt; 一般 &gt; 快速鍵)</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="34"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="37"/>
<source>WARNING: This is an experimental feature.&lt;br/&gt;It will not play back scripts frame perfectly with the current, imperfect syncing method.</source>
<translation>警告:這是實驗性功能。&lt;br/&gt;由於不完善的同步方式,可能無法完整的重現。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="51"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="54"/>
<source>Settings</source>
<translation>設定</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="57"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="60"/>
<source>Enable TAS features</source>
<translation>啟用 TAS 功能</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="64"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="67"/>
<source>Loop script</source>
<translation>循環腳本</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="74"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="77"/>
<source>Pause execution during loads</source>
<translation>載入畫面時暫停執行</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="88"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="91"/>
<source>Script Directory</source>
<translation>腳本資料夾</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="94"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="97"/>
<source>Path</source>
<translation>路徑</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_tas.ui" line="101"/>
+ <location filename="../../src/yuzu/configuration/configure_tas.ui" line="104"/>
<source>...</source>
<translation>...</translation>
</message>
@@ -3978,7 +4028,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.ui" line="49"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="154"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="159"/>
<source>Verify</source>
<translation>驗證</translation>
</message>
@@ -4065,7 +4115,7 @@ Drag points to change position, or double-click table cells to edit values.</sou
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_web.cpp" line="91"/>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="165"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="170"/>
<source>Unspecified</source>
<translation>未指定</translation>
</message>
@@ -4080,17 +4130,36 @@ Drag points to change position, or double-click table cells to edit values.</sou
<translation>Token 未驗證,因此未儲存您對使用者名稱和 Token 的修改。</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="144"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="141"/>
+ <source>Unverified, please click Verify before saving configuration</source>
+ <comment>Tooltip</comment>
+ <translation>令牌未验证,请在保存配置之前进行验证。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="147"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="149"/>
<source>Verifying...</source>
<translation>驗證中...</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="166"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="164"/>
+ <source>Verified</source>
+ <comment>Tooltip</comment>
+ <translation>已验证</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="169"/>
<source>Verification failed</source>
+ <comment>Tooltip</comment>
<translation>驗證失敗</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_web.cpp" line="167"/>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="171"/>
+ <source>Verification failed</source>
+ <translation>驗證失敗</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/configuration/configure_web.cpp" line="172"/>
<source>Verification failed. Check that you have entered your token correctly, and that your internet connection is working.</source>
<translation>驗證失敗。請檢查您输入的 Token 是否正確,並確保您的網路連線正常。</translation>
</message>
@@ -4159,12 +4228,12 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>DirectConnectWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="112"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="125"/>
<source>Connecting</source>
<translation>连接中</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="117"/>
+ <location filename="../../src/yuzu/multiplayer/direct_connect.cpp" line="130"/>
<source>Connect</source>
<translation>连接</translation>
</message>
@@ -4172,912 +4241,892 @@ Drag points to change position, or double-click table cells to edit values.</sou
<context>
<name>GMainWindow</name>
<message>
- <location filename="../../src/yuzu/main.cpp" line="183"/>
+ <location filename="../../src/yuzu/main.cpp" line="187"/>
<source>&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;Anonymous data is collected&lt;/a&gt; to help improve yuzu. &lt;br/&gt;&lt;br/&gt;Would you like to share your usage data with us?</source>
<translation>我們&lt;a href=&apos;https://yuzu-emu.org/help/feature/telemetry/&apos;&gt;蒐集匿名的資料&lt;/a&gt;以幫助改善 yuzu。&lt;br/&gt;&lt;br/&gt;您願意和我們分享您的使用資料嗎?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="186"/>
+ <location filename="../../src/yuzu/main.cpp" line="190"/>
<source>Telemetry</source>
<translation>遙測</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="388"/>
+ <location filename="../../src/yuzu/main.cpp" line="391"/>
<source>Broken Vulkan Installation Detected</source>
<translation>检测到 Vulkan 的安装已损坏</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="389"/>
+ <location filename="../../src/yuzu/main.cpp" line="392"/>
<source>Vulkan initialization failed during boot.&lt;br&gt;&lt;br&gt;Click &lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;here for instructions to fix the issue&lt;/a&gt;.</source>
<translation>Vulkan 初始化失败。&lt;br&gt;&lt;br&gt;点击&lt;a href=&apos;https://yuzu-emu.org/wiki/faq/#yuzu-starts-with-the-error-broken-vulkan-installation-detected&apos;&gt;这里&lt;/a&gt;获取此问题的相关信息。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="717"/>
+ <location filename="../../src/yuzu/main.cpp" line="720"/>
<source>Loading Web Applet...</source>
<translation>載入 Web Applet...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="764"/>
<location filename="../../src/yuzu/main.cpp" line="767"/>
+ <location filename="../../src/yuzu/main.cpp" line="770"/>
<source>Disable Web Applet</source>
<translation>停用 Web Applet</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="768"/>
+ <location filename="../../src/yuzu/main.cpp" line="771"/>
<source>Disabling the web applet can lead to undefined behavior and should only be used with Super Mario 3D All-Stars. Are you sure you want to disable the web applet?
(This can be re-enabled in the Debug settings.)</source>
<translation>禁用 Web 应用程序可能会导致未知的行为,且只能在《超级马里奥 3D 全明星》中使用。您确定要禁用 Web 应用程序吗?
(您可以在调试选项中重新启用它。)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="875"/>
+ <location filename="../../src/yuzu/main.cpp" line="878"/>
<source>The amount of shaders currently being built</source>
<translation>目前正在建構的著色器數量</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="877"/>
+ <location filename="../../src/yuzu/main.cpp" line="880"/>
<source>The current selected resolution scaling multiplier.</source>
<translation>目前選擇的解析度縮放比例。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="880"/>
+ <location filename="../../src/yuzu/main.cpp" line="883"/>
<source>Current emulation speed. Values higher or lower than 100% indicate emulation is running faster or slower than a Switch.</source>
<translation>目前的模擬速度。高於或低於 100% 表示比實際 Switch 執行速度更快或更慢。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="883"/>
+ <location filename="../../src/yuzu/main.cpp" line="886"/>
<source>How many frames per second the game is currently displaying. This will vary from game to game and scene to scene.</source>
<translation>遊戲即時 FPS。會因遊戲和場景的不同而改變。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="887"/>
+ <location filename="../../src/yuzu/main.cpp" line="890"/>
<source>Time taken to emulate a Switch frame, not counting framelimiting or v-sync. For full-speed emulation this should be at most 16.67 ms.</source>
<translation>在不考慮幀數限制和垂直同步的情況下模擬一個 Switch 畫格的實際時間,若要全速模擬,此數值不得超過 16.67 毫秒。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>VULKAN</source>
<translation>VULKAN</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="966"/>
+ <location filename="../../src/yuzu/main.cpp" line="969"/>
<source>OPENGL</source>
<translation>OPENGL</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1028"/>
+ <location filename="../../src/yuzu/main.cpp" line="1031"/>
<source>&amp;Clear Recent Files</source>
<translation>清除最近的檔案(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1335"/>
+ <location filename="../../src/yuzu/main.cpp" line="1338"/>
<source>&amp;Continue</source>
<translation>繼續(&amp;C)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1337"/>
+ <location filename="../../src/yuzu/main.cpp" line="1340"/>
<source>&amp;Pause</source>
<translation>&amp;暫停</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1415"/>
+ <location filename="../../src/yuzu/main.cpp" line="1418"/>
<source>yuzu is running a game</source>
<extracomment>TRANSLATORS: This string is shown to the user to explain why yuzu needs to prevent the computer from sleeping</extracomment>
<translation>yuzu 正在執行中</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1546"/>
+ <location filename="../../src/yuzu/main.cpp" line="1549"/>
<source>Warning Outdated Game Format</source>
<translation>過時遊戲格式警告</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1547"/>
+ <location filename="../../src/yuzu/main.cpp" line="1550"/>
<source>You are using the deconstructed ROM directory format for this game, which is an outdated format that has been superseded by others such as NCA, NAX, XCI, or NSP. Deconstructed ROM directories lack icons, metadata, and update support.&lt;br&gt;&lt;br&gt;For an explanation of the various Switch formats yuzu supports, &lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;check out our wiki&lt;/a&gt;. This message will not be shown again.</source>
<translation>此遊戲為解構的 ROM 資料夾格式,這是一種過時的格式,已被其他格式取代,如 NCA、NAX、XCI、NSP。解構的 ROM 目錄缺少圖示、中繼資料和更新支援。&lt;br&gt;&lt;br&gt;有關 yuzu 支援的各種 Switch 格式說明,&lt;a href=&apos;https://yuzu-emu.org/wiki/overview-of-switch-game-formats&apos;&gt;請參閱我們的 wiki &lt;/a&gt;。此訊息將不再顯示。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1559"/>
- <location filename="../../src/yuzu/main.cpp" line="1593"/>
+ <location filename="../../src/yuzu/main.cpp" line="1562"/>
+ <location filename="../../src/yuzu/main.cpp" line="1596"/>
<source>Error while loading ROM!</source>
<translation>載入 ROM 時發生錯誤!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1560"/>
+ <location filename="../../src/yuzu/main.cpp" line="1563"/>
<source>The ROM format is not supported.</source>
<translation>此 ROM 格式不支援</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1564"/>
+ <location filename="../../src/yuzu/main.cpp" line="1567"/>
<source>An error occurred initializing the video core.</source>
<translation>初始化視訊核心時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1565"/>
+ <location filename="../../src/yuzu/main.cpp" line="1568"/>
<source>yuzu has encountered an error while running the video core. This is usually caused by outdated GPU drivers, including integrated ones. Please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;How to Upload the Log File&lt;/a&gt;. </source>
<translation>yuzu 在執行視訊核心時發生錯誤。 這可能是 GPU 驅動程序過舊造成的。 詳細資訊請查閱日誌檔案。 關於日誌檔案的更多資訊,請參考以下頁面:&lt;a href=&apos;https://yuzu-emu.org/help/reference/log-files/&apos;&gt;如何上傳日誌檔案&lt;/a&gt;。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1580"/>
+ <location filename="../../src/yuzu/main.cpp" line="1583"/>
<source>Error while loading ROM! %1</source>
<comment>%1 signifies a numeric error code.</comment>
<translation>載入 ROM 時發生錯誤!%1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1583"/>
+ <location filename="../../src/yuzu/main.cpp" line="1586"/>
<source>%1&lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to redump your files.&lt;br&gt;You can refer to the yuzu wiki&lt;/a&gt; or the yuzu Discord&lt;/a&gt; for help.</source>
<comment>%1 signifies an error string.</comment>
<translation>%1&lt;br&gt;請參閱 &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;yuzu 快速指引&lt;/a&gt;以重新傾印檔案。&lt;br&gt;您可以前往 yuzu 的 wiki&lt;/a&gt; 或 Discord 社群&lt;/a&gt;以獲得幫助。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1594"/>
+ <location filename="../../src/yuzu/main.cpp" line="1597"/>
<source>An unknown error occurred. Please see the log for more details.</source>
<translation>發生未知錯誤,請檢視紀錄了解細節。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(64-bit)</source>
<translation>(64-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1725"/>
+ <location filename="../../src/yuzu/main.cpp" line="1729"/>
<source>(32-bit)</source>
<translation>(32-bit)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1726"/>
+ <location filename="../../src/yuzu/main.cpp" line="1730"/>
<source>%1 %2</source>
<comment>%1 is the title name. %2 indicates if the title is 64-bit or 32-bit</comment>
<translation>%1 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1876"/>
+ <location filename="../../src/yuzu/main.cpp" line="1880"/>
<source>Save Data</source>
<translation>儲存資料</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1924"/>
+ <location filename="../../src/yuzu/main.cpp" line="1928"/>
<source>Mod Data</source>
<translation>模組資料</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1936"/>
+ <location filename="../../src/yuzu/main.cpp" line="1940"/>
<source>Error Opening %1 Folder</source>
<translation>開啟資料夾 %1 時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1937"/>
- <location filename="../../src/yuzu/main.cpp" line="2343"/>
+ <location filename="../../src/yuzu/main.cpp" line="1941"/>
+ <location filename="../../src/yuzu/main.cpp" line="2347"/>
<source>Folder does not exist!</source>
<translation>資料夾不存在</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1949"/>
+ <location filename="../../src/yuzu/main.cpp" line="1953"/>
<source>Error Opening Transferable Shader Cache</source>
<translation>開啟通用著色器快取位置時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="1950"/>
+ <location filename="../../src/yuzu/main.cpp" line="1954"/>
<source>Failed to create the shader cache directory for this title.</source>
<translation>無法新增此遊戲的著色器快取資料夾。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2002"/>
+ <location filename="../../src/yuzu/main.cpp" line="2006"/>
<source>Contents</source>
<translation>內容</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2004"/>
+ <location filename="../../src/yuzu/main.cpp" line="2008"/>
<source>Update</source>
<translation>遊戲更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2006"/>
+ <location filename="../../src/yuzu/main.cpp" line="2010"/>
<source>DLC</source>
<translation>DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Entry</source>
<translation>移除項目</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2013"/>
+ <location filename="../../src/yuzu/main.cpp" line="2017"/>
<source>Remove Installed Game %1?</source>
<translation>移除已安裝的遊戲「%1」?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2043"/>
- <location filename="../../src/yuzu/main.cpp" line="2059"/>
- <location filename="../../src/yuzu/main.cpp" line="2090"/>
- <location filename="../../src/yuzu/main.cpp" line="2151"/>
- <location filename="../../src/yuzu/main.cpp" line="2169"/>
- <location filename="../../src/yuzu/main.cpp" line="2192"/>
+ <location filename="../../src/yuzu/main.cpp" line="2047"/>
+ <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2094"/>
+ <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2196"/>
<source>Successfully Removed</source>
<translation>移除成功</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2044"/>
+ <location filename="../../src/yuzu/main.cpp" line="2048"/>
<source>Successfully removed the installed base game.</source>
<translation>成功移除已安裝的遊戲。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2047"/>
- <location filename="../../src/yuzu/main.cpp" line="2062"/>
- <location filename="../../src/yuzu/main.cpp" line="2085"/>
+ <location filename="../../src/yuzu/main.cpp" line="2051"/>
+ <location filename="../../src/yuzu/main.cpp" line="2066"/>
+ <location filename="../../src/yuzu/main.cpp" line="2089"/>
<source>Error Removing %1</source>
<translation>移除 %1 失敗</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2048"/>
+ <location filename="../../src/yuzu/main.cpp" line="2052"/>
<source>The base game is not installed in the NAND and cannot be removed.</source>
<translation>此遊戲並非安裝在內部儲存空間,因此無法移除。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2060"/>
+ <location filename="../../src/yuzu/main.cpp" line="2064"/>
<source>Successfully removed the installed update.</source>
<translation>成功移除已安裝的遊戲更新。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2063"/>
+ <location filename="../../src/yuzu/main.cpp" line="2067"/>
<source>There is no update installed for this title.</source>
<translation>此遊戲沒有已安裝的更新。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2086"/>
+ <location filename="../../src/yuzu/main.cpp" line="2090"/>
<source>There are no DLC installed for this title.</source>
<translation>此遊戲沒有已安裝的 DLC。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2091"/>
+ <location filename="../../src/yuzu/main.cpp" line="2095"/>
<source>Successfully removed %1 installed DLC.</source>
<translation>成功移除遊戲 %1 已安裝的 DLC。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2099"/>
+ <location filename="../../src/yuzu/main.cpp" line="2103"/>
<source>Delete OpenGL Transferable Shader Cache?</source>
<translation>刪除 OpenGL 模式的著色器快取?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2101"/>
+ <location filename="../../src/yuzu/main.cpp" line="2105"/>
<source>Delete Vulkan Transferable Shader Cache?</source>
<translation>刪除 Vulkan 模式的著色器快取?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2103"/>
+ <location filename="../../src/yuzu/main.cpp" line="2107"/>
<source>Delete All Transferable Shader Caches?</source>
<translation>刪除所有的著色器快取?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2105"/>
+ <location filename="../../src/yuzu/main.cpp" line="2109"/>
<source>Remove Custom Game Configuration?</source>
<translation>移除額外遊戲設定?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2111"/>
+ <location filename="../../src/yuzu/main.cpp" line="2115"/>
<source>Remove File</source>
<translation>刪除檔案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2146"/>
- <location filename="../../src/yuzu/main.cpp" line="2154"/>
+ <location filename="../../src/yuzu/main.cpp" line="2150"/>
+ <location filename="../../src/yuzu/main.cpp" line="2158"/>
<source>Error Removing Transferable Shader Cache</source>
<translation>刪除通用著色器快取時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2147"/>
- <location filename="../../src/yuzu/main.cpp" line="2165"/>
+ <location filename="../../src/yuzu/main.cpp" line="2151"/>
+ <location filename="../../src/yuzu/main.cpp" line="2169"/>
<source>A shader cache for this title does not exist.</source>
<translation>此遊戲沒有著色器快取</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2152"/>
+ <location filename="../../src/yuzu/main.cpp" line="2156"/>
<source>Successfully removed the transferable shader cache.</source>
<translation>成功刪除著色器快取。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2155"/>
+ <location filename="../../src/yuzu/main.cpp" line="2159"/>
<source>Failed to remove the transferable shader cache.</source>
<translation>刪除通用著色器快取失敗。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2164"/>
- <location filename="../../src/yuzu/main.cpp" line="2172"/>
+ <location filename="../../src/yuzu/main.cpp" line="2168"/>
+ <location filename="../../src/yuzu/main.cpp" line="2176"/>
<source>Error Removing Transferable Shader Caches</source>
<translation>刪除通用著色器快取時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2170"/>
+ <location filename="../../src/yuzu/main.cpp" line="2174"/>
<source>Successfully removed the transferable shader caches.</source>
<translation>成功刪除通用著色器快取。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2173"/>
+ <location filename="../../src/yuzu/main.cpp" line="2177"/>
<source>Failed to remove the transferable shader cache directory.</source>
<translation>無法刪除著色器快取資料夾。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2186"/>
- <location filename="../../src/yuzu/main.cpp" line="2195"/>
+ <location filename="../../src/yuzu/main.cpp" line="2190"/>
+ <location filename="../../src/yuzu/main.cpp" line="2199"/>
<source>Error Removing Custom Configuration</source>
<translation>移除額外遊戲設定時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2187"/>
+ <location filename="../../src/yuzu/main.cpp" line="2191"/>
<source>A custom configuration for this title does not exist.</source>
<translation>此遊戲沒有額外設定。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2193"/>
+ <location filename="../../src/yuzu/main.cpp" line="2197"/>
<source>Successfully removed the custom game configuration.</source>
<translation>成功移除額外遊戲設定。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2196"/>
+ <location filename="../../src/yuzu/main.cpp" line="2200"/>
<source>Failed to remove the custom game configuration.</source>
<translation>移除額外遊戲設定失敗。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2203"/>
- <location filename="../../src/yuzu/main.cpp" line="2282"/>
+ <location filename="../../src/yuzu/main.cpp" line="2207"/>
+ <location filename="../../src/yuzu/main.cpp" line="2286"/>
<source>RomFS Extraction Failed!</source>
<translation>RomFS 抽取失敗!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2204"/>
+ <location filename="../../src/yuzu/main.cpp" line="2208"/>
<source>There was an error copying the RomFS files or the user cancelled the operation.</source>
<translation>複製 RomFS 檔案時發生錯誤或使用者取消動作。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Full</source>
<translation>全部</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2262"/>
+ <location filename="../../src/yuzu/main.cpp" line="2266"/>
<source>Skeleton</source>
<translation>部分</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2264"/>
+ <location filename="../../src/yuzu/main.cpp" line="2268"/>
<source>Select RomFS Dump Mode</source>
<translation>選擇RomFS傾印模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2265"/>
+ <location filename="../../src/yuzu/main.cpp" line="2269"/>
<source>Please select the how you would like the RomFS dumped.&lt;br&gt;Full will copy all of the files into the new directory while &lt;br&gt;skeleton will only create the directory structure.</source>
<translation>請選擇如何傾印 RomFS。&lt;br&gt;「全部」會複製所有檔案到新資料夾中,而&lt;br&gt;「部分」只會建立資料夾結構。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2283"/>
+ <location filename="../../src/yuzu/main.cpp" line="2287"/>
<source>There is not enough free space at %1 to extract the RomFS. Please free up space or select a different dump directory at Emulation &gt; Configure &gt; System &gt; Filesystem &gt; Dump Root</source>
<translation>%1 沒有足夠的空間用於抽取 RomFS。請確保有足夠的空間或於模擬 &gt; 設定 &gt;系統 &gt;檔案系統 &gt; 傾印根目錄中選擇其他資料夾。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
<source>Extracting RomFS...</source>
<translation>抽取 RomFS 中...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2290"/>
- <location filename="../../src/yuzu/main.cpp" line="2476"/>
+ <location filename="../../src/yuzu/main.cpp" line="2294"/>
+ <location filename="../../src/yuzu/main.cpp" line="2480"/>
<source>Cancel</source>
<translation>取消</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2297"/>
+ <location filename="../../src/yuzu/main.cpp" line="2301"/>
<source>RomFS Extraction Succeeded!</source>
<translation>RomFS 抽取完成!</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2298"/>
+ <location filename="../../src/yuzu/main.cpp" line="2302"/>
<source>The operation completed successfully.</source>
<translation>動作已成功完成</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2342"/>
+ <location filename="../../src/yuzu/main.cpp" line="2346"/>
<source>Error Opening %1</source>
<translation>開啟 %1 時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2351"/>
+ <location filename="../../src/yuzu/main.cpp" line="2355"/>
<source>Select Directory</source>
<translation>選擇資料夾</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2378"/>
+ <location filename="../../src/yuzu/main.cpp" line="2382"/>
<source>Properties</source>
<translation>屬性</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2379"/>
+ <location filename="../../src/yuzu/main.cpp" line="2383"/>
<source>The game properties could not be loaded.</source>
<translation>無法載入遊戲屬性</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2396"/>
+ <location filename="../../src/yuzu/main.cpp" line="2400"/>
<source>Switch Executable (%1);;All Files (*.*)</source>
<comment>%1 is an identifier for the Switch executable file extensions.</comment>
<translation>Switch 執行檔 (%1);;所有檔案 (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2400"/>
+ <location filename="../../src/yuzu/main.cpp" line="2404"/>
<source>Load File</source>
<translation>開啟檔案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2413"/>
+ <location filename="../../src/yuzu/main.cpp" line="2417"/>
<source>Open Extracted ROM Directory</source>
<translation>開啟已抽取的 ROM 資料夾</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2424"/>
+ <location filename="../../src/yuzu/main.cpp" line="2428"/>
<source>Invalid Directory Selected</source>
<translation>選擇的資料夾無效</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2425"/>
+ <location filename="../../src/yuzu/main.cpp" line="2429"/>
<source>The directory you have selected does not contain a &apos;main&apos; file.</source>
<translation>選擇的資料夾未包含「main」檔案。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2435"/>
+ <location filename="../../src/yuzu/main.cpp" line="2439"/>
<source>Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge Image (*.xci)</source>
<translation>可安装的 Switch 檔案 (*.nca *.nsp *.xci);;Nintendo Content Archive (*.nca);;Nintendo Submission Package (*.nsp);;NX 卡帶映像 (*.xci)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2440"/>
+ <location filename="../../src/yuzu/main.cpp" line="2444"/>
<source>Install Files</source>
<translation>安裝檔案</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2484"/>
+ <location filename="../../src/yuzu/main.cpp" line="2488"/>
<source>%n file(s) remaining</source>
<translation><numerusform>剩餘 %n 個檔案</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2486"/>
+ <location filename="../../src/yuzu/main.cpp" line="2490"/>
<source>Installing file &quot;%1&quot;...</source>
<translation>正在安裝檔案「%1」...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2532"/>
- <location filename="../../src/yuzu/main.cpp" line="2546"/>
+ <location filename="../../src/yuzu/main.cpp" line="2536"/>
+ <location filename="../../src/yuzu/main.cpp" line="2550"/>
<source>Install Results</source>
<translation>安裝結果</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2533"/>
+ <location filename="../../src/yuzu/main.cpp" line="2537"/>
<source>To avoid possible conflicts, we discourage users from installing base games to the NAND.
Please, only use this feature to install updates and DLC.</source>
<translation>為了避免潛在的衝突,不建議將遊戲本體安裝至內部儲存空間。
此功能僅用於安裝遊戲更新和 DLC。</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2539"/>
+ <location filename="../../src/yuzu/main.cpp" line="2543"/>
<source>%n file(s) were newly installed
</source>
<translation><numerusform>最近安裝了 %n 個檔案
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2542"/>
+ <location filename="../../src/yuzu/main.cpp" line="2546"/>
<source>%n file(s) were overwritten
</source>
<translation><numerusform>%n 個檔案被取代
</numerusform></translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="2544"/>
+ <location filename="../../src/yuzu/main.cpp" line="2548"/>
<source>%n file(s) failed to install
</source>
<translation><numerusform>%n 個檔案安裝失敗</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2645"/>
+ <location filename="../../src/yuzu/main.cpp" line="2649"/>
<source>System Application</source>
<translation>系統應用程式</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2646"/>
+ <location filename="../../src/yuzu/main.cpp" line="2650"/>
<source>System Archive</source>
<translation>系統檔案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2647"/>
+ <location filename="../../src/yuzu/main.cpp" line="2651"/>
<source>System Application Update</source>
<translation>系統應用程式更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2648"/>
+ <location filename="../../src/yuzu/main.cpp" line="2652"/>
<source>Firmware Package (Type A)</source>
<translation>韌體包(A型)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2649"/>
+ <location filename="../../src/yuzu/main.cpp" line="2653"/>
<source>Firmware Package (Type B)</source>
<translation>韌體包(B型)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2650"/>
+ <location filename="../../src/yuzu/main.cpp" line="2654"/>
<source>Game</source>
<translation>遊戲</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2651"/>
+ <location filename="../../src/yuzu/main.cpp" line="2655"/>
<source>Game Update</source>
<translation>遊戲更新</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2652"/>
+ <location filename="../../src/yuzu/main.cpp" line="2656"/>
<source>Game DLC</source>
<translation>遊戲 DLC</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2653"/>
+ <location filename="../../src/yuzu/main.cpp" line="2657"/>
<source>Delta Title</source>
<translation>Delta Title</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2656"/>
+ <location filename="../../src/yuzu/main.cpp" line="2660"/>
<source>Select NCA Install Type...</source>
<translation>選擇 NCA 安裝類型...</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2657"/>
+ <location filename="../../src/yuzu/main.cpp" line="2661"/>
<source>Please select the type of title you would like to install this NCA as:
(In most instances, the default &apos;Game&apos; is fine.)</source>
<translation>請選擇此 NCA 的安裝類型:
(在多數情況下,選擇預設的「遊戲」即可。)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2663"/>
+ <location filename="../../src/yuzu/main.cpp" line="2667"/>
<source>Failed to Install</source>
<translation>安裝失敗</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2664"/>
+ <location filename="../../src/yuzu/main.cpp" line="2668"/>
<source>The title type you selected for the NCA is invalid.</source>
<translation>選擇的 NCA 安裝類型無效。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2699"/>
+ <location filename="../../src/yuzu/main.cpp" line="2703"/>
<source>File not found</source>
<translation>找不到檔案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2700"/>
+ <location filename="../../src/yuzu/main.cpp" line="2704"/>
<source>File &quot;%1&quot; not found</source>
<translation>找不到「%1」檔案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2770"/>
+ <location filename="../../src/yuzu/main.cpp" line="2774"/>
<source>OK</source>
<translation>確定</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2784"/>
+ <location filename="../../src/yuzu/main.cpp" line="2788"/>
<source>Missing yuzu Account</source>
<translation>未設定 yuzu 帳號</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2785"/>
+ <location filename="../../src/yuzu/main.cpp" line="2789"/>
<source>In order to submit a game compatibility test case, you must link your yuzu account.&lt;br&gt;&lt;br/&gt;To link your yuzu account, go to Emulation &amp;gt; Configuration &amp;gt; Web.</source>
<translation>為了上傳相容性測試結果,您必須登入 yuzu 帳號。&lt;br&gt;&lt;br/&gt;欲登入 yuzu 帳號請至模擬 &amp;gt; 設定 &amp;gt; 網路。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2795"/>
+ <location filename="../../src/yuzu/main.cpp" line="2799"/>
<source>Error opening URL</source>
<translation>開啟 URL 時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="2796"/>
+ <location filename="../../src/yuzu/main.cpp" line="2800"/>
<source>Unable to open the URL &quot;%1&quot;.</source>
<translation>無法開啟 URL:「%1」。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3091"/>
+ <location filename="../../src/yuzu/main.cpp" line="3096"/>
<source>TAS Recording</source>
<translation>TAS 錄製</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3092"/>
+ <location filename="../../src/yuzu/main.cpp" line="3097"/>
<source>Overwrite file of player 1?</source>
<translation>覆寫玩家 1 的檔案?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3118"/>
+ <location filename="../../src/yuzu/main.cpp" line="3123"/>
<source>Invalid config detected</source>
<translation>偵測到無效設定</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3119"/>
+ <location filename="../../src/yuzu/main.cpp" line="3124"/>
<source>Handheld controller can&apos;t be used on docked mode. Pro controller will be selected.</source>
<translation>掌機手把無法在主機模式中使用。將會選擇 Pro 手把。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>Error</source>
<translation>错误</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3212"/>
- <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3217"/>
+ <location filename="../../src/yuzu/main.cpp" line="3229"/>
<source>The current game is not looking for amiibos</source>
<translation>当前游戏并没有在寻找 Amiibos</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>Amiibo</source>
<translation>Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3219"/>
- <location filename="../../src/yuzu/main.cpp" line="3253"/>
+ <location filename="../../src/yuzu/main.cpp" line="3224"/>
+ <location filename="../../src/yuzu/main.cpp" line="3258"/>
<source>The current amiibo has been removed</source>
<translation>当前的 Amiibo 已被移除。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3230"/>
+ <location filename="../../src/yuzu/main.cpp" line="3235"/>
<source>Amiibo File (%1);; All Files (*.*)</source>
<translation>Amiibo 檔案 (%1);; 所有檔案 (*.*)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3231"/>
+ <location filename="../../src/yuzu/main.cpp" line="3236"/>
<source>Load Amiibo</source>
<translation>開啟 Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3259"/>
- <source>Error opening Amiibo data file</source>
- <translation>開啟 Amiibo 檔案時發生錯誤</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3260"/>
- <source>Unable to open Amiibo file &quot;%1&quot; for reading.</source>
- <translation>無法開啟 Amiibo 檔案 %1。</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3268"/>
- <source>Error reading Amiibo data file</source>
- <translation>讀取 Amiibo 檔案時發生錯誤</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3269"/>
- <source>Unable to fully read Amiibo data. Expected to read %1 bytes, but was only able to read %2 bytes.</source>
- <translation>無法讀取完整的 Amiibo 資料。應讀取 %1 位元組,但實際僅讀取到 %2 位元組。</translation>
- </message>
- <message>
- <location filename="../../src/yuzu/main.cpp" line="3277"/>
+ <location filename="../../src/yuzu/main.cpp" line="3263"/>
<source>Error loading Amiibo data</source>
<translation>載入 Amiibo 資料時發生錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3278"/>
+ <location filename="../../src/yuzu/main.cpp" line="3264"/>
<source>Unable to load Amiibo data.</source>
<translation>無法載入 Amiibo 資料。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3327"/>
+ <location filename="../../src/yuzu/main.cpp" line="3313"/>
<source>Capture Screenshot</source>
<translation>截圖</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3328"/>
+ <location filename="../../src/yuzu/main.cpp" line="3314"/>
<source>PNG Image (*.png)</source>
<translation>PNG 圖片 (*.png)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3394"/>
+ <location filename="../../src/yuzu/main.cpp" line="3380"/>
<source>TAS state: Running %1/%2</source>
<translation>TAS 狀態:正在執行 %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3396"/>
+ <location filename="../../src/yuzu/main.cpp" line="3382"/>
<source>TAS state: Recording %1</source>
<translation>TAS 狀態:正在錄製 %1</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3398"/>
+ <location filename="../../src/yuzu/main.cpp" line="3384"/>
<source>TAS state: Idle %1/%2</source>
<translation>TAS 狀態:閒置 %1/%2</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3400"/>
+ <location filename="../../src/yuzu/main.cpp" line="3386"/>
<source>TAS State: Invalid</source>
<translation>TAS 狀態:無效</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Stop Running</source>
<translation>&amp;停止執行</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3414"/>
+ <location filename="../../src/yuzu/main.cpp" line="3400"/>
<source>&amp;Start</source>
<translation>開始(&amp;S)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>Stop R&amp;ecording</source>
<translation>停止錄製</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3415"/>
+ <location filename="../../src/yuzu/main.cpp" line="3401"/>
<source>R&amp;ecord</source>
<translation>錄製 (&amp;E)</translation>
</message>
<message numerus="yes">
- <location filename="../../src/yuzu/main.cpp" line="3439"/>
+ <location filename="../../src/yuzu/main.cpp" line="3425"/>
<source>Building: %n shader(s)</source>
<translation><numerusform>正在編譯 %n 個著色器檔案</numerusform></translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3448"/>
+ <location filename="../../src/yuzu/main.cpp" line="3434"/>
<source>Scale: %1x</source>
<comment>%1 is the resolution scaling factor</comment>
<translation>縮放比例:%1x</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3451"/>
+ <location filename="../../src/yuzu/main.cpp" line="3437"/>
<source>Speed: %1% / %2%</source>
<translation>速度:%1% / %2%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3455"/>
+ <location filename="../../src/yuzu/main.cpp" line="3441"/>
<source>Speed: %1%</source>
<translation>速度:%1%</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3459"/>
+ <location filename="../../src/yuzu/main.cpp" line="3445"/>
<source>Game: %1 FPS (Unlocked)</source>
<translation>遊戲: %1 FPS(未限制)</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3461"/>
+ <location filename="../../src/yuzu/main.cpp" line="3447"/>
<source>Game: %1 FPS</source>
<translation>遊戲:%1 FPS</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3463"/>
+ <location filename="../../src/yuzu/main.cpp" line="3449"/>
<source>Frame: %1 ms</source>
<translation>畫格延遲:%1 ms</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3474"/>
+ <location filename="../../src/yuzu/main.cpp" line="3460"/>
<source>GPU NORMAL</source>
<translation>GPU 一般效能</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3479"/>
+ <location filename="../../src/yuzu/main.cpp" line="3465"/>
<source>GPU HIGH</source>
<translation>GPU 高效能</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3484"/>
+ <location filename="../../src/yuzu/main.cpp" line="3470"/>
<source>GPU EXTREME</source>
<translation>GPU 最高效能</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3489"/>
+ <location filename="../../src/yuzu/main.cpp" line="3475"/>
<source>GPU ERROR</source>
<translation>GPU 錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>DOCKED</source>
<translation>主机模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3498"/>
+ <location filename="../../src/yuzu/main.cpp" line="3484"/>
<source>HANDHELD</source>
<translation>掌机模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3505"/>
+ <location filename="../../src/yuzu/main.cpp" line="3491"/>
<source>NEAREST</source>
<translation>最近鄰域</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3508"/>
- <location filename="../../src/yuzu/main.cpp" line="3523"/>
+ <location filename="../../src/yuzu/main.cpp" line="3494"/>
+ <location filename="../../src/yuzu/main.cpp" line="3509"/>
<source>BILINEAR</source>
<translation>雙線性</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3511"/>
+ <location filename="../../src/yuzu/main.cpp" line="3497"/>
<source>BICUBIC</source>
<translation>雙三次</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3514"/>
+ <location filename="../../src/yuzu/main.cpp" line="3500"/>
<source>GAUSSIAN</source>
<translation>高斯</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3517"/>
+ <location filename="../../src/yuzu/main.cpp" line="3503"/>
<source>SCALEFORCE</source>
<translation>強制縮放</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3520"/>
+ <location filename="../../src/yuzu/main.cpp" line="3506"/>
<source>FSR</source>
<translation>FSR</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3532"/>
- <location filename="../../src/yuzu/main.cpp" line="3538"/>
+ <location filename="../../src/yuzu/main.cpp" line="3518"/>
+ <location filename="../../src/yuzu/main.cpp" line="3524"/>
<source>NO AA</source>
<translation>抗鋸齒關</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3535"/>
+ <location filename="../../src/yuzu/main.cpp" line="3521"/>
<source>FXAA</source>
<translation>FXAA</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3612"/>
+ <location filename="../../src/yuzu/main.cpp" line="3598"/>
<source>The game you are trying to load requires additional files from your Switch to be dumped before playing.&lt;br/&gt;&lt;br/&gt;For more information on dumping these files, please see the following wiki page: &lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;Dumping System Archives and the Shared Fonts from a Switch Console&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>此遊戲需要從您的 Switch 傾印額外檔案。&lt;br/&gt;&lt;br/&gt;有關傾印這些檔案的更多資訊,請參閱以下 wiki 網頁:Dumping System Archives and the Shared Fonts from a Switch Console&lt;a href=&apos;https://yuzu-emu.org/wiki/dumping-system-archives-and-the-shared-fonts-from-a-switch-console/&apos;&gt;。&lt;br/&gt;&lt;br/&gt;您要停止並回到遊戲清單嗎?繼續模擬可能會導致當機、存檔損毀或其他錯誤。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3627"/>
+ <location filename="../../src/yuzu/main.cpp" line="3613"/>
<source>yuzu was unable to locate a Switch system archive. %1</source>
<translation>Yuzu 找不到 Switch 系統檔案 %1 </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3629"/>
+ <location filename="../../src/yuzu/main.cpp" line="3615"/>
<source>yuzu was unable to locate a Switch system archive: %1. %2</source>
<translation>Yuzu 找不到 Switch 系統檔案:%1。%2 </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3633"/>
+ <location filename="../../src/yuzu/main.cpp" line="3619"/>
<source>System Archive Not Found</source>
<translation>找不到系統檔案</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3635"/>
+ <location filename="../../src/yuzu/main.cpp" line="3621"/>
<source>System Archive Missing</source>
<translation>系統檔案遺失</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3641"/>
+ <location filename="../../src/yuzu/main.cpp" line="3627"/>
<source>yuzu was unable to locate the Switch shared fonts. %1</source>
<translation>Yuzu 找不到 Switch 共享字型 %1 </translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3642"/>
+ <location filename="../../src/yuzu/main.cpp" line="3628"/>
<source>Shared Fonts Not Found</source>
<translation>找不到共享字型</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3644"/>
+ <location filename="../../src/yuzu/main.cpp" line="3630"/>
<source>Shared Font Missing</source>
<translation>遺失共享字型</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3650"/>
+ <location filename="../../src/yuzu/main.cpp" line="3636"/>
<source>Fatal Error</source>
<translation>嚴重錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3651"/>
+ <location filename="../../src/yuzu/main.cpp" line="3637"/>
<source>yuzu has encountered a fatal error, please see the log for more details. For more information on accessing the log, please see the following page: &lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;Would you like to quit back to the game list? Continuing emulation may result in crashes, corrupted save data, or other bugs.</source>
<translation>yuzu 發生嚴重錯誤,請檢視紀錄以了解細節。更多資訊請參閱網頁:&lt;a href=&apos;https://community.citra-emu.org/t/how-to-upload-the-log-file/296&apos;&gt;How to Upload the Log File&lt;/a&gt;。&lt;br/&gt;&lt;br/&gt;您要停止模擬並回到遊戲清單嗎?繼續模擬可能會導致當機、存檔損毀或其他錯誤。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3660"/>
+ <location filename="../../src/yuzu/main.cpp" line="3646"/>
<source>Fatal Error encountered</source>
<translation>發生嚴重錯誤</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3683"/>
+ <location filename="../../src/yuzu/main.cpp" line="3669"/>
<source>Confirm Key Rederivation</source>
<translation>確認重新產生金鑰</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3684"/>
+ <location filename="../../src/yuzu/main.cpp" line="3670"/>
<source>You are about to force rederive all of your keys.
If you do not know what this means or what you are doing,
this is a potentially destructive action.
@@ -5093,37 +5142,37 @@ This will delete your autogenerated key files and re-run the key derivation modu
這將刪除您自動產生的金鑰檔案並重新執行產生金鑰模組。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3716"/>
+ <location filename="../../src/yuzu/main.cpp" line="3702"/>
<source>Missing fuses</source>
<translation>遺失項目</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3719"/>
+ <location filename="../../src/yuzu/main.cpp" line="3705"/>
<source> - Missing BOOT0</source>
<translation>- 遺失 BOOT0</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3722"/>
+ <location filename="../../src/yuzu/main.cpp" line="3708"/>
<source> - Missing BCPKG2-1-Normal-Main</source>
<translation> - 遺失 BCPKG2-1-Normal-Main</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3725"/>
+ <location filename="../../src/yuzu/main.cpp" line="3711"/>
<source> - Missing PRODINFO</source>
<translation>- 遺失 PRODINFO</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3729"/>
+ <location filename="../../src/yuzu/main.cpp" line="3715"/>
<source>Derivation Components Missing</source>
<translation>遺失產生元件</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3730"/>
+ <location filename="../../src/yuzu/main.cpp" line="3716"/>
<source>Encryption keys are missing. &lt;br&gt;Please follow &lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;the yuzu quickstart guide&lt;/a&gt; to get all your keys, firmware and games.&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)&lt;/small&gt;</source>
<translation>缺少加密金鑰。 &lt;br&gt;請按照&lt;a href=&apos;https://yuzu-emu.org/help/quickstart/&apos;&gt;《Yuzu快速入門指南》來取得所有金鑰、韌體、遊戲&lt;br&gt;&lt;br&gt;&lt;small&gt;(%1)。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3739"/>
+ <location filename="../../src/yuzu/main.cpp" line="3725"/>
<source>Deriving keys...
This may take up to a minute depending
on your system&apos;s performance.</source>
@@ -5132,39 +5181,39 @@ on your system&apos;s performance.</source>
您的系統效能。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3741"/>
+ <location filename="../../src/yuzu/main.cpp" line="3727"/>
<source>Deriving Keys</source>
<translation>產生金鑰</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3786"/>
+ <location filename="../../src/yuzu/main.cpp" line="3772"/>
<source>Select RomFS Dump Target</source>
<translation>選擇 RomFS 傾印目標</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3787"/>
+ <location filename="../../src/yuzu/main.cpp" line="3773"/>
<source>Please select which RomFS you would like to dump.</source>
<translation>請選擇希望傾印的 RomFS。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3802"/>
+ <location filename="../../src/yuzu/main.cpp" line="3788"/>
<source>Are you sure you want to close yuzu?</source>
<translation>您確定要關閉 yuzu 嗎?</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3803"/>
- <location filename="../../src/yuzu/main.cpp" line="3901"/>
- <location filename="../../src/yuzu/main.cpp" line="3914"/>
+ <location filename="../../src/yuzu/main.cpp" line="3789"/>
+ <location filename="../../src/yuzu/main.cpp" line="3887"/>
+ <location filename="../../src/yuzu/main.cpp" line="3900"/>
<source>yuzu</source>
<translation>yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3902"/>
+ <location filename="../../src/yuzu/main.cpp" line="3888"/>
<source>Are you sure you want to stop the emulation? Any unsaved progress will be lost.</source>
<translation>您確定要停止模擬嗎?未儲存的進度將會遺失。</translation>
</message>
<message>
- <location filename="../../src/yuzu/main.cpp" line="3911"/>
+ <location filename="../../src/yuzu/main.cpp" line="3897"/>
<source>The currently running application has requested yuzu to not exit.
Would you like to bypass this and exit anyway?</source>
@@ -5541,12 +5590,12 @@ Screen.</source>
<context>
<name>HostRoomWindow</name>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="169"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="182"/>
<source>Error</source>
<translation>错误</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="170"/>
+ <location filename="../../src/yuzu/multiplayer/host_room.cpp" line="183"/>
<source>Failed to announce the room to the public lobby. In order to host a room publicly, you must have a valid yuzu account configured in Emulation -&gt; Configure -&gt; Web. If you do not want to publish a room in the public lobby, then select Unlisted instead.
Debug Message: </source>
<translation>向公共大厅公开房间时失败。为了管理公开房间,您必须在模拟 -&gt; 设置 -&gt; 网络中配置有效的 yuzu 帐户。如果不想在公共大厅中公开房间,请选择“未列出”。
@@ -5556,11 +5605,12 @@ Debug Message: </source>
<context>
<name>Hotkeys</name>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<source>Audio Mute/Unmute</source>
<translation>静音/关闭静音</translation>
</message>
<message>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="73"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
@@ -5582,112 +5632,111 @@ Debug Message: </source>
<location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
<source>Main Window</source>
<translation>主窗口</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="74"/>
<source>Audio Volume Down</source>
<translation>调低音量</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="75"/>
<source>Audio Volume Up</source>
<translation>调高音量</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="76"/>
<source>Capture Screenshot</source>
<translation>截圖</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="77"/>
<source>Change Adapting Filter</source>
<translation>更改窗口滤镜</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="78"/>
<source>Change Docked Mode</source>
<translation>更改运行模式</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="79"/>
<source>Change GPU Accuracy</source>
<translation>更改 GPU 精度</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="80"/>
<source>Continue/Pause Emulation</source>
<translation>继续/暂停模拟</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="81"/>
<source>Exit Fullscreen</source>
<translation>退出全屏</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="82"/>
<source>Exit yuzu</source>
<translation>退出 yuzu</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="83"/>
<source>Fullscreen</source>
<translation>全屏</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="84"/>
<source>Load File</source>
<translation>開啟檔案</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="85"/>
<source>Load/Remove Amiibo</source>
<translation>加载/移除 Amiibo</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="86"/>
<source>Restart Emulation</source>
<translation>重新启动模拟</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="87"/>
<source>Stop Emulation</source>
<translation>停止模拟</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="88"/>
<source>TAS Record</source>
<translation>TAS 录制</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="89"/>
<source>TAS Reset</source>
<translation>重设 TAS</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="90"/>
<source>TAS Start/Stop</source>
<translation>TAS 开始/停止</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="91"/>
<source>Toggle Filter Bar</source>
<translation>切换搜索栏</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="92"/>
<source>Toggle Framerate Limit</source>
<translation>切换帧率限制</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="93"/>
<source>Toggle Mouse Panning</source>
<translation>切换鼠标平移</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/config.cpp" line="95"/>
+ <location filename="../../src/yuzu/configuration/config.cpp" line="94"/>
<source>Toggle Status Bar</source>
<translation>切换状态栏</translation>
</message>
@@ -5801,42 +5850,42 @@ Debug Message: </source>
<translation>刷新游戏大厅</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password Required to Join</source>
<translation>加入此房间需要密码</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="106"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="108"/>
<source>Password:</source>
<translation>密码:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="192"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="206"/>
<source>Room Name</source>
<translation>房间名称</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="193"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="207"/>
<source>Preferred Game</source>
<translation>首选游戏</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="194"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="208"/>
<source>Host</source>
<translation>管理</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="195"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="209"/>
<source>Players</source>
<translation>玩家</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="202"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="216"/>
<source>Refreshing</source>
<translation>刷新中</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="259"/>
+ <location filename="../../src/yuzu/multiplayer/lobby.cpp" line="273"/>
<source>Refresh List</source>
<translation>刷新列表</translation>
</message>
@@ -6163,7 +6212,7 @@ Debug Message: </source>
<message>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="97"/>
<location filename="../../src/yuzu/multiplayer/state.cpp" line="123"/>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="260"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="259"/>
<source>Connected</source>
<translation>已連線</translation>
</message>
@@ -6186,7 +6235,7 @@ Debug Message: </source>
调试信息:</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/state.cpp" line="254"/>
+ <location filename="../../src/yuzu/multiplayer/state.cpp" line="253"/>
<source>New Messages Received</source>
<translation>收到了新消息</translation>
</message>
@@ -6291,22 +6340,41 @@ They may have left the room.</source>
他们可能已经离开了房间。</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="65"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="53"/>
+ <source>No network interface is selected.
+Please go to Configure -&gt; System -&gt; Network and make a selection.</source>
+ <translation>未选择网络接口。
+请于设置 -&gt; 系统 -&gt; 网络中进行相关设置。</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="68"/>
+ <source>Game already running</source>
+ <translation>游戏已在运行中</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="69"/>
+ <source>Joining a room when the game is already running is discouraged and can cause the room feature not to work correctly.
+Proceed anyway?</source>
+ <translation>不推荐游戏正在运行时加入房间,这可能会导致房间的某些功能出现异常。
+是否继续?</translation>
+ </message>
+ <message>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="75"/>
<source>Leave Room</source>
<translation>离开房间</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="66"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="76"/>
<source>You are about to close the room. Any network connections will be closed.</source>
<translation>您正要关闭房间。所有的网络连接都将关闭。</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="71"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="81"/>
<source>Disconnect</source>
<translation>断开连接</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="72"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="82"/>
<source>You are about to leave the room. Any network connections will be closed.</source>
<translation>您正要离开房间。所有的网络连接都将关闭。</translation>
</message>
@@ -6314,7 +6382,7 @@ They may have left the room.</source>
<context>
<name>NetworkMessage::ErrorManager</name>
<message>
- <location filename="../../src/yuzu/multiplayer/message.cpp" line="60"/>
+ <location filename="../../src/yuzu/multiplayer/message.cpp" line="63"/>
<source>Error</source>
<translation>错误</translation>
</message>
@@ -6373,7 +6441,7 @@ p, li { white-space: pre-wrap; }
<translation>%1 正在玩 %2</translation>
</message>
<message>
- <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="134"/>
+ <location filename="../../src/yuzu/multiplayer/chat_room.cpp" line="136"/>
<source>Not playing a game</source>
<translation>不在玩游戏</translation>
</message>
@@ -6428,7 +6496,7 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="318"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="384"/>
<location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="159"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="225"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="226"/>
<source>[not set]</source>
<translation>[未設定]</translation>
</message>
@@ -6443,10 +6511,10 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="411"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="415"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="419"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="248"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="252"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="256"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="260"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="249"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="253"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="257"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="261"/>
<source>Axis %1%2</source>
<translation>Axis %1%2</translation>
</message>
@@ -6460,9 +6528,9 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="378"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="392"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="422"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="219"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="233"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="263"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="220"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="234"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="264"/>
<source>[unknown]</source>
<translation>[未知]</translation>
</message>
@@ -6627,15 +6695,15 @@ p, li { white-space: pre-wrap; }
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="332"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="173"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="174"/>
<source>[invalid]</source>
<translation>[無效]</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="342"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="366"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="183"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="207"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="184"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="208"/>
<source>%1%2Hat %3</source>
<translation>%1%2Hat 控制器 %3</translation>
</message>
@@ -6643,35 +6711,35 @@ p, li { white-space: pre-wrap; }
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="346"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="369"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="372"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="187"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="210"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="213"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="188"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="211"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="214"/>
<source>%1%2Axis %3</source>
<translation>%1%2軸 %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="352"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="193"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="194"/>
<source>%1%2Axis %3,%4,%5</source>
<translation>%1%2軸 %3,%4,%5</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="356"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="197"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="198"/>
<source>%1%2Motion %3</source>
<translation>%1%2體感 %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="360"/>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="375"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="201"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="216"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="202"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="217"/>
<source>%1%2Button %3</source>
<translation>%1%2按鈕 %3</translation>
</message>
<message>
<location filename="../../src/yuzu/configuration/configure_ringcon.cpp" line="402"/>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="243"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="244"/>
<source>[unused]</source>
<translation>[未使用]</translation>
</message>
@@ -6712,7 +6780,7 @@ p, li { white-space: pre-wrap; }
<translation>額外按鍵</translation>
</message>
<message>
- <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="169"/>
+ <location filename="../../src/yuzu/configuration/configure_input_player.cpp" line="170"/>
<source>%1%2%3</source>
<translation>%1%2%3</translation>
</message>
diff --git a/dist/qt_themes/colorful/icons/48x48/bad_folder.png b/dist/qt_themes/colorful/icons/48x48/bad_folder.png
index a7ab7a1f6..34069c6b2 100644
--- a/dist/qt_themes/colorful/icons/48x48/bad_folder.png
+++ b/dist/qt_themes/colorful/icons/48x48/bad_folder.png
Binary files differ
diff --git a/dist/qt_themes/default/icons/256x256/plus_folder.png b/dist/qt_themes/default/icons/256x256/plus_folder.png
index 3a49669a3..f44c80c3a 100644
--- a/dist/qt_themes/default/icons/256x256/plus_folder.png
+++ b/dist/qt_themes/default/icons/256x256/plus_folder.png
Binary files differ
diff --git a/dist/qt_themes/default/icons/256x256/yuzu.png b/dist/qt_themes/default/icons/256x256/yuzu.png
index bd5cf533f..238adeb89 100644
--- a/dist/qt_themes/default/icons/256x256/yuzu.png
+++ b/dist/qt_themes/default/icons/256x256/yuzu.png
Binary files differ
diff --git a/dist/qt_themes/qdarkstyle/icons/256x256/plus_folder.png b/dist/qt_themes/qdarkstyle/icons/256x256/plus_folder.png
index 002101114..14c90fea5 100644
--- a/dist/qt_themes/qdarkstyle/icons/256x256/plus_folder.png
+++ b/dist/qt_themes/qdarkstyle/icons/256x256/plus_folder.png
Binary files differ
diff --git a/externals/ffmpeg/CMakeLists.txt b/externals/ffmpeg/CMakeLists.txt
index 20ad716ea..0baac8e17 100644
--- a/externals/ffmpeg/CMakeLists.txt
+++ b/externals/ffmpeg/CMakeLists.txt
@@ -43,7 +43,7 @@ if (NOT WIN32)
CACHE PATH "Paths to FFmpeg libraries" FORCE)
endforeach()
- Include(FindPkgConfig REQUIRED)
+ find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBVA libva)
pkg_check_modules(CUDA cuda)
pkg_check_modules(FFNVCODEC ffnvcodec)
diff --git a/externals/libusb/CMakeLists.txt b/externals/libusb/CMakeLists.txt
index 055b89295..3cb1b3687 100644
--- a/externals/libusb/CMakeLists.txt
+++ b/externals/libusb/CMakeLists.txt
@@ -108,7 +108,7 @@ if (MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux") OR APPLE)
target_include_directories(usb INTERFACE "${LIBUSB_INCLUDE_DIRS}")
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
- Include(FindPkgConfig)
+ find_package(PkgConfig)
pkg_check_modules(LIBUDEV REQUIRED libudev)
if (LIBUDEV_FOUND)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 54de1dc94..0ac3d254e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -58,13 +58,11 @@ if (MSVC)
# Warnings
/W3
- /we4018 # 'expression': signed/unsigned mismatch
+ /WX
+
/we4062 # Enumerator 'identifier' in a switch of enum 'enumeration' is not handled
- /we4101 # 'identifier': unreferenced local variable
/we4189 # 'identifier': local variable is initialized but not referenced
/we4265 # 'class': class has virtual functions, but destructor is not virtual
- /we4267 # 'var': conversion from 'size_t' to 'type', possible loss of data
- /we4305 # 'context': truncation from 'type1' to 'type2'
/we4388 # 'expression': signed/unsigned mismatch
/we4389 # 'operator': signed/unsigned mismatch
/we4456 # Declaration of 'identifier' hides previous local declaration
@@ -75,10 +73,13 @@ if (MSVC)
/we4547 # 'operator': operator before comma has no effect; expected operator with side-effect
/we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'?
/we4555 # Expression has no effect; expected expression with side-effect
- /we4715 # 'function': not all control paths return a value
- /we4834 # Discarding return value of function with 'nodiscard' attribute
+ /we4826 # Conversion from 'type1' to 'type2' is sign-extended. This may cause unexpected runtime behavior.
/we5038 # data member 'member1' will be initialized after data member 'member2'
+ /we5233 # explicit lambda capture 'identifier' is not used
/we5245 # 'function': unreferenced function with internal linkage has been removed
+
+ /wd4100 # 'identifier': unreferenced formal parameter
+ /wd4324 # 'struct_name': structure was padded due to __declspec(align())
)
if (USE_CCACHE)
@@ -99,28 +100,23 @@ if (MSVC)
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG /MANIFEST:NO /INCREMENTAL:NO /OPT:REF,ICF" CACHE STRING "" FORCE)
else()
add_compile_options(
- -Wall
- -Werror=array-bounds
- -Werror=implicit-fallthrough
+ -Werror=all
+ -Werror=extra
-Werror=missing-declarations
- -Werror=missing-field-initializers
- -Werror=reorder
-Werror=shadow
- -Werror=sign-compare
- -Werror=switch
- -Werror=uninitialized
- -Werror=unused-function
- -Werror=unused-result
- -Werror=unused-variable
- -Wextra
- -Wmissing-declarations
+ -Werror=unused
+
-Wno-attributes
-Wno-invalid-offsetof
-Wno-unused-parameter
+
+ $<$<CXX_COMPILER_ID:Clang>:-Wno-braced-scalar-init>
+ $<$<CXX_COMPILER_ID:Clang>:-Wno-unused-private-field>
)
if (ARCHITECTURE_x86_64)
add_compile_options("-mcx16")
+ add_compile_options("-fwrapv")
endif()
if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt
index 144f1bab2..0a1f3bf18 100644
--- a/src/audio_core/CMakeLists.txt
+++ b/src/audio_core/CMakeLists.txt
@@ -206,20 +206,11 @@ if (MSVC)
/we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data
/we4245 # 'conversion': conversion from 'type1' to 'type2', signed/unsigned mismatch
/we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
- /we4456 # Declaration of 'identifier' hides previous local declaration
- /we4457 # Declaration of 'identifier' hides function parameter
- /we4458 # Declaration of 'identifier' hides class member
- /we4459 # Declaration of 'identifier' hides global declaration
+ /we4800 # Implicit conversion from 'type' to bool. Possible information loss
)
else()
target_compile_options(audio_core PRIVATE
-Werror=conversion
- -Werror=ignored-qualifiers
- -Werror=shadow
- -Werror=unused-variable
-
- $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter>
- $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable>
-Wno-sign-conversion
)
diff --git a/src/audio_core/audio_core.cpp b/src/audio_core/audio_core.cpp
index c845330cd..07a679c32 100644
--- a/src/audio_core/audio_core.cpp
+++ b/src/audio_core/audio_core.cpp
@@ -8,7 +8,7 @@
namespace AudioCore {
-AudioCore::AudioCore(Core::System& system) : audio_manager{std::make_unique<AudioManager>(system)} {
+AudioCore::AudioCore(Core::System& system) : audio_manager{std::make_unique<AudioManager>()} {
CreateSinks();
// Must be created after the sinks
adsp = std::make_unique<AudioRenderer::ADSP::ADSP>(system, *output_sink);
diff --git a/src/audio_core/audio_manager.cpp b/src/audio_core/audio_manager.cpp
index 2f1bba9c3..2acde668e 100644
--- a/src/audio_core/audio_manager.cpp
+++ b/src/audio_core/audio_manager.cpp
@@ -1,14 +1,13 @@
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-#include "audio_core/audio_in_manager.h"
#include "audio_core/audio_manager.h"
-#include "audio_core/audio_out_manager.h"
#include "core/core.h"
+#include "core/hle/service/audio/errors.h"
namespace AudioCore {
-AudioManager::AudioManager(Core::System& system_) : system{system_} {
+AudioManager::AudioManager() {
thread = std::jthread([this]() { ThreadFunc(); });
}
@@ -27,7 +26,7 @@ Result AudioManager::SetOutManager(BufferEventFunc buffer_func) {
const auto index{events.GetManagerIndex(Event::Type::AudioOutManager)};
if (buffer_events[index] == nullptr) {
- buffer_events[index] = buffer_func;
+ buffer_events[index] = std::move(buffer_func);
needs_update = true;
events.SetAudioEvent(Event::Type::AudioOutManager, true);
}
@@ -43,7 +42,7 @@ Result AudioManager::SetInManager(BufferEventFunc buffer_func) {
const auto index{events.GetManagerIndex(Event::Type::AudioInManager)};
if (buffer_events[index] == nullptr) {
- buffer_events[index] = buffer_func;
+ buffer_events[index] = std::move(buffer_func);
needs_update = true;
events.SetAudioEvent(Event::Type::AudioInManager, true);
}
@@ -60,19 +59,21 @@ void AudioManager::ThreadFunc() {
running = true;
while (running) {
- auto timed_out{events.Wait(l, std::chrono::seconds(2))};
+ const auto timed_out{events.Wait(l, std::chrono::seconds(2))};
if (events.CheckAudioEventSet(Event::Type::Max)) {
break;
}
for (size_t i = 0; i < buffer_events.size(); i++) {
- if (events.CheckAudioEventSet(Event::Type(i)) || timed_out) {
+ const auto event_type = static_cast<Event::Type>(i);
+
+ if (events.CheckAudioEventSet(event_type) || timed_out) {
if (buffer_events[i]) {
buffer_events[i]();
}
}
- events.SetAudioEvent(Event::Type(i), false);
+ events.SetAudioEvent(event_type, false);
}
}
}
diff --git a/src/audio_core/audio_manager.h b/src/audio_core/audio_manager.h
index 8cbd95e22..abf077de4 100644
--- a/src/audio_core/audio_manager.h
+++ b/src/audio_core/audio_manager.h
@@ -10,22 +10,11 @@
#include <thread>
#include "audio_core/audio_event.h"
-#include "core/hle/service/audio/errors.h"
-namespace Core {
-class System;
-}
+union Result;
namespace AudioCore {
-namespace AudioOut {
-class Manager;
-}
-
-namespace AudioIn {
-class Manager;
-}
-
/**
* The AudioManager's main purpose is to wait for buffer events for the audio in and out managers,
* and call an associated callback to release buffers.
@@ -43,7 +32,7 @@ class AudioManager {
using BufferEventFunc = std::function<void()>;
public:
- explicit AudioManager(Core::System& system);
+ explicit AudioManager();
/**
* Shutdown the audio manager.
@@ -80,10 +69,6 @@ private:
*/
void ThreadFunc();
- /// Core system
- Core::System& system;
- /// Have sessions started palying?
- bool sessions_started{};
/// Is the main thread running?
std::atomic<bool> running{};
/// Unused
diff --git a/src/audio_core/in/audio_in_system.cpp b/src/audio_core/in/audio_in_system.cpp
index e7f918a47..4324cafd8 100644
--- a/src/audio_core/in/audio_in_system.cpp
+++ b/src/audio_core/in/audio_in_system.cpp
@@ -23,7 +23,7 @@ System::~System() {
void System::Finalize() {
Stop();
session->Finalize();
- buffer_event->GetWritableEvent().Signal();
+ buffer_event->Signal();
}
void System::StartSession() {
@@ -56,7 +56,7 @@ Result System::IsConfigValid(const std::string_view device_name,
return ResultSuccess;
}
-Result System::Initialize(std::string& device_name, const AudioInParameter& in_params,
+Result System::Initialize(std::string device_name, const AudioInParameter& in_params,
const u32 handle_, const u64 applet_resource_user_id_) {
auto result{IsConfigValid(device_name, in_params)};
if (result.IsError()) {
@@ -142,7 +142,7 @@ void System::ReleaseBuffers() {
if (signal) {
// Signal if any buffer was released, or if none are registered, we need more.
- buffer_event->GetWritableEvent().Signal();
+ buffer_event->Signal();
}
}
@@ -159,7 +159,7 @@ bool System::FlushAudioInBuffers() {
buffers.FlushBuffers(buffers_released);
if (buffers_released > 0) {
- buffer_event->GetWritableEvent().Signal();
+ buffer_event->Signal();
}
return true;
}
diff --git a/src/audio_core/in/audio_in_system.h b/src/audio_core/in/audio_in_system.h
index b9dc0e60f..1c5154638 100644
--- a/src/audio_core/in/audio_in_system.h
+++ b/src/audio_core/in/audio_in_system.h
@@ -97,7 +97,7 @@ public:
* @param applet_resource_user_id - Unused.
* @return Result code.
*/
- Result Initialize(std::string& device_name, const AudioInParameter& in_params, u32 handle,
+ Result Initialize(std::string device_name, const AudioInParameter& in_params, u32 handle,
u64 applet_resource_user_id);
/**
diff --git a/src/audio_core/out/audio_out_system.cpp b/src/audio_core/out/audio_out_system.cpp
index 8b907590a..a66208ed9 100644
--- a/src/audio_core/out/audio_out_system.cpp
+++ b/src/audio_core/out/audio_out_system.cpp
@@ -24,7 +24,7 @@ System::~System() {
void System::Finalize() {
Stop();
session->Finalize();
- buffer_event->GetWritableEvent().Signal();
+ buffer_event->Signal();
}
std::string_view System::GetDefaultOutputDeviceName() const {
@@ -49,8 +49,8 @@ Result System::IsConfigValid(std::string_view device_name,
return Service::Audio::ERR_INVALID_CHANNEL_COUNT;
}
-Result System::Initialize(std::string& device_name, const AudioOutParameter& in_params, u32 handle_,
- u64& applet_resource_user_id_) {
+Result System::Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle_,
+ u64 applet_resource_user_id_) {
auto result = IsConfigValid(device_name, in_params);
if (result.IsError()) {
return result;
@@ -141,7 +141,7 @@ void System::ReleaseBuffers() {
bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session)};
if (signal) {
// Signal if any buffer was released, or if none are registered, we need more.
- buffer_event->GetWritableEvent().Signal();
+ buffer_event->Signal();
}
}
@@ -158,7 +158,7 @@ bool System::FlushAudioOutBuffers() {
buffers.FlushBuffers(buffers_released);
if (buffers_released > 0) {
- buffer_event->GetWritableEvent().Signal();
+ buffer_event->Signal();
}
return true;
}
diff --git a/src/audio_core/out/audio_out_system.h b/src/audio_core/out/audio_out_system.h
index 0817b2f37..b95cb91be 100644
--- a/src/audio_core/out/audio_out_system.h
+++ b/src/audio_core/out/audio_out_system.h
@@ -88,8 +88,8 @@ public:
* @param applet_resource_user_id - Unused.
* @return Result code.
*/
- Result Initialize(std::string& device_name, const AudioOutParameter& in_params, u32 handle,
- u64& applet_resource_user_id);
+ Result Initialize(std::string device_name, const AudioOutParameter& in_params, u32 handle,
+ u64 applet_resource_user_id);
/**
* Start this system.
diff --git a/src/audio_core/renderer/adsp/audio_renderer.cpp b/src/audio_core/renderer/adsp/audio_renderer.cpp
index bafe4822a..d982ef630 100644
--- a/src/audio_core/renderer/adsp/audio_renderer.cpp
+++ b/src/audio_core/renderer/adsp/audio_renderer.cpp
@@ -47,7 +47,7 @@ RenderMessage AudioRenderer_Mailbox::ADSPWaitMessage() {
return msg;
}
-CommandBuffer& AudioRenderer_Mailbox::GetCommandBuffer(const s32 session_id) {
+CommandBuffer& AudioRenderer_Mailbox::GetCommandBuffer(const u32 session_id) {
return command_buffers[session_id];
}
@@ -132,7 +132,7 @@ void AudioRenderer::CreateSinkStreams() {
}
void AudioRenderer::ThreadFunc() {
- constexpr char name[]{"yuzu:AudioRenderer"};
+ constexpr char name[]{"AudioRenderer"};
MicroProfileOnThreadCreate(name);
Common::SetCurrentThreadName(name);
Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);
diff --git a/src/audio_core/renderer/adsp/audio_renderer.h b/src/audio_core/renderer/adsp/audio_renderer.h
index 02e923c84..151f38c1b 100644
--- a/src/audio_core/renderer/adsp/audio_renderer.h
+++ b/src/audio_core/renderer/adsp/audio_renderer.h
@@ -83,7 +83,7 @@ public:
* @param session_id - The session id to get (0 or 1).
* @return The command buffer.
*/
- CommandBuffer& GetCommandBuffer(s32 session_id);
+ CommandBuffer& GetCommandBuffer(u32 session_id);
/**
* Set the command buffer with the given session id (0 or 1).
diff --git a/src/audio_core/renderer/behavior/info_updater.cpp b/src/audio_core/renderer/behavior/info_updater.cpp
index c0a307b89..574cf0982 100644
--- a/src/audio_core/renderer/behavior/info_updater.cpp
+++ b/src/audio_core/renderer/behavior/info_updater.cpp
@@ -91,7 +91,7 @@ Result InfoUpdater::UpdateVoices(VoiceContext& voice_context,
voice_info.Initialize();
for (u32 channel = 0; channel < in_param.channel_count; channel++) {
- std::memset(voice_states[channel], 0, sizeof(VoiceState));
+ *voice_states[channel] = {};
}
}
diff --git a/src/audio_core/renderer/command/effect/biquad_filter.cpp b/src/audio_core/renderer/command/effect/biquad_filter.cpp
index 1baae74fd..edb30ce72 100644
--- a/src/audio_core/renderer/command/effect/biquad_filter.cpp
+++ b/src/audio_core/renderer/command/effect/biquad_filter.cpp
@@ -94,7 +94,7 @@ void BiquadFilterCommand::Dump([[maybe_unused]] const ADSP::CommandListProcessor
void BiquadFilterCommand::Process(const ADSP::CommandListProcessor& processor) {
auto state_{reinterpret_cast<VoiceState::BiquadFilterState*>(state)};
if (needs_init) {
- std::memset(state_, 0, sizeof(VoiceState::BiquadFilterState));
+ *state_ = {};
}
auto input_buffer{
diff --git a/src/audio_core/renderer/command/effect/multi_tap_biquad_filter.cpp b/src/audio_core/renderer/command/effect/multi_tap_biquad_filter.cpp
index b3c3ba4ba..48a7cba8a 100644
--- a/src/audio_core/renderer/command/effect/multi_tap_biquad_filter.cpp
+++ b/src/audio_core/renderer/command/effect/multi_tap_biquad_filter.cpp
@@ -30,7 +30,7 @@ void MultiTapBiquadFilterCommand::Process(const ADSP::CommandListProcessor& proc
for (u32 i = 0; i < filter_tap_count; i++) {
auto state{reinterpret_cast<VoiceState::BiquadFilterState*>(states[i])};
if (needs_init[i]) {
- std::memset(state, 0, sizeof(VoiceState::BiquadFilterState));
+ *state = {};
}
ApplyBiquadFilterFloat(output_buffer, input_buffer, biquads[i].b, biquads[i].a, *state,
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp
index 7a217969e..4fac30c7c 100644
--- a/src/audio_core/renderer/system.cpp
+++ b/src/audio_core/renderer/system.cpp
@@ -98,9 +98,8 @@ System::System(Core::System& core_, Kernel::KEvent* adsp_rendered_event_)
: core{core_}, adsp{core.AudioCore().GetADSP()}, adsp_rendered_event{adsp_rendered_event_} {}
Result System::Initialize(const AudioRendererParameterInternal& params,
- Kernel::KTransferMemory* transfer_memory, const u64 transfer_memory_size,
- const u32 process_handle_, const u64 applet_resource_user_id_,
- const s32 session_id_) {
+ Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
+ u32 process_handle_, u64 applet_resource_user_id_, s32 session_id_) {
if (!CheckValidRevision(params.revision)) {
return Service::Audio::ERR_INVALID_REVISION;
}
@@ -354,6 +353,8 @@ Result System::Initialize(const AudioRendererParameterInternal& params,
render_time_limit_percent = 100;
drop_voice = params.voice_drop_enabled && params.execution_mode == ExecutionMode::Auto;
+ drop_voice_param = 1.0f;
+ num_voices_dropped = 0;
allocator.Align(0x40);
command_workbuffer_size = allocator.GetRemainingSize();
@@ -534,7 +535,7 @@ Result System::Update(std::span<const u8> input, std::span<u8> performance, std:
return result;
}
- adsp_rendered_event->GetWritableEvent().Clear();
+ adsp_rendered_event->Clear();
num_times_updated++;
const auto end_time{core.CoreTiming().GetClockTicks()};
@@ -547,7 +548,7 @@ u32 System::GetRenderingTimeLimit() const {
return render_time_limit_percent;
}
-void System::SetRenderingTimeLimit(const u32 limit) {
+void System::SetRenderingTimeLimit(u32 limit) {
render_time_limit_percent = limit;
}
@@ -625,7 +626,7 @@ void System::SendCommandToDsp() {
reset_command_buffers = false;
command_buffer_size = command_size;
if (remaining_command_count == 0) {
- adsp_rendered_event->GetWritableEvent().Signal();
+ adsp_rendered_event->Signal();
}
} else {
adsp.ClearRemainCount(session_id);
@@ -635,7 +636,7 @@ void System::SendCommandToDsp() {
}
u64 System::GenerateCommand(std::span<u8> in_command_buffer,
- [[maybe_unused]] const u64 command_buffer_size_) {
+ [[maybe_unused]] u64 command_buffer_size_) {
PoolMapper::ClearUseState(memory_pool_workbuffer, memory_pool_count);
const auto start_time{core.CoreTiming().GetClockTicks()};
@@ -693,7 +694,8 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer,
voice_context.SortInfo();
- const auto start_estimated_time{command_buffer.estimated_process_time};
+ const auto start_estimated_time{drop_voice_param *
+ static_cast<f32>(command_buffer.estimated_process_time)};
command_generator.GenerateVoiceCommands();
command_generator.GenerateSubMixCommands();
@@ -712,11 +714,16 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer,
render_context.behavior->IsAudioRendererProcessingTimeLimit70PercentSupported();
time_limit_percent = 70.0f;
}
+
+ const auto end_estimated_time{drop_voice_param *
+ static_cast<f32>(command_buffer.estimated_process_time)};
+ const auto estimated_time{start_estimated_time - end_estimated_time};
+
const auto time_limit{static_cast<u32>(
- static_cast<f32>(start_estimated_time - command_buffer.estimated_process_time) +
- (((time_limit_percent / 100.0f) * 2'880'000.0) *
- (static_cast<f32>(render_time_limit_percent) / 100.0f)))};
- num_voices_dropped = DropVoices(command_buffer, start_estimated_time, time_limit);
+ estimated_time + (((time_limit_percent / 100.0f) * 2'880'000.0) *
+ (static_cast<f32>(render_time_limit_percent) / 100.0f)))};
+ num_voices_dropped =
+ DropVoices(command_buffer, static_cast<u32>(start_estimated_time), time_limit);
}
command_list_header->buffer_size = command_buffer.size;
@@ -737,24 +744,33 @@ u64 System::GenerateCommand(std::span<u8> in_command_buffer,
return command_buffer.size;
}
-u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_process_time,
- const u32 time_limit) {
+f32 System::GetVoiceDropParameter() const {
+ return drop_voice_param;
+}
+
+void System::SetVoiceDropParameter(f32 voice_drop_) {
+ drop_voice_param = voice_drop_;
+}
+
+u32 System::DropVoices(CommandBuffer& command_buffer, u32 estimated_process_time, u32 time_limit) {
u32 i{0};
auto command_list{command_buffer.command_list.data() + sizeof(CommandListHeader)};
- ICommand* cmd{};
+ ICommand* cmd{nullptr};
- for (; i < command_buffer.count; i++) {
+ // Find a first valid voice to drop
+ while (i < command_buffer.count) {
cmd = reinterpret_cast<ICommand*>(command_list);
- if (cmd->type != CommandId::Performance &&
- cmd->type != CommandId::DataSourcePcmInt16Version1 &&
- cmd->type != CommandId::DataSourcePcmInt16Version2 &&
- cmd->type != CommandId::DataSourcePcmFloatVersion1 &&
- cmd->type != CommandId::DataSourcePcmFloatVersion2 &&
- cmd->type != CommandId::DataSourceAdpcmVersion1 &&
- cmd->type != CommandId::DataSourceAdpcmVersion2) {
+ if (cmd->type == CommandId::Performance ||
+ cmd->type == CommandId::DataSourcePcmInt16Version1 ||
+ cmd->type == CommandId::DataSourcePcmInt16Version2 ||
+ cmd->type == CommandId::DataSourcePcmFloatVersion1 ||
+ cmd->type == CommandId::DataSourcePcmFloatVersion2 ||
+ cmd->type == CommandId::DataSourceAdpcmVersion1 ||
+ cmd->type == CommandId::DataSourceAdpcmVersion2) {
break;
}
command_list += cmd->size;
+ i++;
}
if (cmd == nullptr || command_buffer.count == 0 || i >= command_buffer.count) {
@@ -767,6 +783,7 @@ u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_proces
const auto node_id_type{cmd->node_id >> 28};
const auto node_id_base{cmd->node_id & 0xFFF};
+ // If the new estimated process time falls below the limit, we're done dropping.
if (estimated_process_time <= time_limit) {
break;
}
@@ -775,6 +792,7 @@ u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_proces
break;
}
+ // Don't drop voices marked with the highest priority.
auto& voice_info{voice_context.GetInfo(node_id_base)};
if (voice_info.priority == HighestVoicePriority) {
break;
@@ -783,18 +801,23 @@ u32 System::DropVoices(CommandBuffer& command_buffer, const u32 estimated_proces
voices_dropped++;
voice_info.voice_dropped = true;
- if (i < command_buffer.count) {
- while (cmd->node_id == node_id) {
- if (cmd->type == CommandId::DepopPrepare) {
- cmd->enabled = true;
- } else if (cmd->type == CommandId::Performance || !cmd->enabled) {
- cmd->enabled = false;
- }
- i++;
- command_list += cmd->size;
- cmd = reinterpret_cast<ICommand*>(command_list);
+ // First iteration should drop the voice, and then iterate through all of the commands tied
+ // to the voice. We don't need reverb on a voice which we've just removed, for example.
+ // Depops can't be removed otherwise we'll introduce audio popping, and we don't
+ // remove perf commands. Lower the estimated time for each command dropped.
+ while (i < command_buffer.count && cmd->node_id == node_id) {
+ if (cmd->type == CommandId::DepopPrepare) {
+ cmd->enabled = true;
+ } else if (cmd->enabled && cmd->type != CommandId::Performance) {
+ cmd->enabled = false;
+ estimated_process_time -= static_cast<u32>(
+ drop_voice_param * static_cast<f32>(cmd->estimated_process_time));
}
+ command_list += cmd->size;
+ cmd = reinterpret_cast<ICommand*>(command_list);
+ i++;
}
+ i++;
}
return voices_dropped;
}
diff --git a/src/audio_core/renderer/system.h b/src/audio_core/renderer/system.h
index bcbe65b07..429196e41 100644
--- a/src/audio_core/renderer/system.h
+++ b/src/audio_core/renderer/system.h
@@ -196,6 +196,20 @@ public:
*/
u32 DropVoices(CommandBuffer& command_buffer, u32 estimated_process_time, u32 time_limit);
+ /**
+ * Get the current voice drop parameter.
+ *
+ * @return The current voice drop.
+ */
+ f32 GetVoiceDropParameter() const;
+
+ /**
+ * Set the voice drop parameter.
+ *
+ * @param The new voice drop.
+ */
+ void SetVoiceDropParameter(f32 voice_drop);
+
private:
/// Core system
Core::System& core;
@@ -301,6 +315,8 @@ private:
u32 num_voices_dropped{};
/// Tick that rendering started
u64 render_start_tick{};
+ /// Parameter to control the threshold for dropping voices if the audio graph gets too large
+ f32 drop_voice_param{1.0f};
};
} // namespace AudioRenderer
diff --git a/src/audio_core/renderer/system_manager.cpp b/src/audio_core/renderer/system_manager.cpp
index 9c1331e19..f66b2b890 100644
--- a/src/audio_core/renderer/system_manager.cpp
+++ b/src/audio_core/renderer/system_manager.cpp
@@ -94,7 +94,7 @@ bool SystemManager::Remove(System& system_) {
}
void SystemManager::ThreadFunc() {
- constexpr char name[]{"yuzu:AudioRenderSystemManager"};
+ constexpr char name[]{"AudioRenderSystemManager"};
MicroProfileOnThreadCreate(name);
Common::SetCurrentThreadName(name);
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
diff --git a/src/audio_core/renderer/voice/voice_context.cpp b/src/audio_core/renderer/voice/voice_context.cpp
index eafb51b01..a501a677d 100644
--- a/src/audio_core/renderer/voice/voice_context.cpp
+++ b/src/audio_core/renderer/voice/voice_context.cpp
@@ -74,8 +74,8 @@ void VoiceContext::SortInfo() {
}
std::ranges::sort(sorted_voice_info, [](const VoiceInfo* a, const VoiceInfo* b) {
- return a->priority != b->priority ? a->priority < b->priority
- : a->sort_order < b->sort_order;
+ return a->priority != b->priority ? a->priority > b->priority
+ : a->sort_order > b->sort_order;
});
}
diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp
index 36b115ad6..32c1b1cb3 100644
--- a/src/audio_core/sink/cubeb_sink.cpp
+++ b/src/audio_core/sink/cubeb_sink.cpp
@@ -66,10 +66,10 @@ public:
const auto latency_error = cubeb_get_min_latency(ctx, &params, &minimum_latency);
if (latency_error != CUBEB_OK) {
LOG_CRITICAL(Audio_Sink, "Error getting minimum latency, error: {}", latency_error);
- minimum_latency = 256U;
+ minimum_latency = TargetSampleCount * 2;
}
- minimum_latency = std::max(minimum_latency, 256u);
+ minimum_latency = std::max(minimum_latency, TargetSampleCount * 2);
LOG_INFO(Service_Audio,
"Opening cubeb stream {} type {} with: rate {} channels {} (system channels {}) "
@@ -326,4 +326,31 @@ std::vector<std::string> ListCubebSinkDevices(bool capture) {
return device_list;
}
+u32 GetCubebLatency() {
+ cubeb* ctx;
+
+ if (cubeb_init(&ctx, "yuzu Latency Getter", nullptr) != CUBEB_OK) {
+ LOG_CRITICAL(Audio_Sink, "cubeb_init failed");
+ // Return a large latency so we choose SDL instead.
+ return 10000u;
+ }
+
+ cubeb_stream_params params{};
+ params.rate = TargetSampleRate;
+ params.channels = 2;
+ params.format = CUBEB_SAMPLE_S16LE;
+ params.prefs = CUBEB_STREAM_PREF_NONE;
+ params.layout = CUBEB_LAYOUT_STEREO;
+
+ u32 latency{0};
+ const auto latency_error = cubeb_get_min_latency(ctx, &params, &latency);
+ if (latency_error != CUBEB_OK) {
+ LOG_CRITICAL(Audio_Sink, "Error getting minimum latency, error: {}", latency_error);
+ latency = TargetSampleCount * 2;
+ }
+ latency = std::max(latency, TargetSampleCount * 2);
+ cubeb_destroy(ctx);
+ return latency;
+}
+
} // namespace AudioCore::Sink
diff --git a/src/audio_core/sink/cubeb_sink.h b/src/audio_core/sink/cubeb_sink.h
index 4b0cb160d..3302cb98d 100644
--- a/src/audio_core/sink/cubeb_sink.h
+++ b/src/audio_core/sink/cubeb_sink.h
@@ -96,4 +96,11 @@ private:
*/
std::vector<std::string> ListCubebSinkDevices(bool capture);
+/**
+ * Get the reported latency for this sink.
+ *
+ * @return Minimum latency for this sink.
+ */
+u32 GetCubebLatency();
+
} // namespace AudioCore::Sink
diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp
index 1bd001b94..c138dc628 100644
--- a/src/audio_core/sink/sdl2_sink.cpp
+++ b/src/audio_core/sink/sdl2_sink.cpp
@@ -47,11 +47,7 @@ public:
spec.freq = TargetSampleRate;
spec.channels = static_cast<u8>(device_channels);
spec.format = AUDIO_S16SYS;
- if (type == StreamType::Render) {
- spec.samples = TargetSampleCount;
- } else {
- spec.samples = 1024;
- }
+ spec.samples = TargetSampleCount * 2;
spec.callback = &SDLSinkStream::DataCallback;
spec.userdata = this;
@@ -234,10 +230,16 @@ std::vector<std::string> ListSDLSinkDevices(bool capture) {
const int device_count = SDL_GetNumAudioDevices(capture);
for (int i = 0; i < device_count; ++i) {
- device_list.emplace_back(SDL_GetAudioDeviceName(i, 0));
+ if (const char* name = SDL_GetAudioDeviceName(i, capture)) {
+ device_list.emplace_back(name);
+ }
}
return device_list;
}
+u32 GetSDLLatency() {
+ return TargetSampleCount * 2;
+}
+
} // namespace AudioCore::Sink
diff --git a/src/audio_core/sink/sdl2_sink.h b/src/audio_core/sink/sdl2_sink.h
index f01eddc1b..27ed1ab94 100644
--- a/src/audio_core/sink/sdl2_sink.h
+++ b/src/audio_core/sink/sdl2_sink.h
@@ -87,4 +87,11 @@ private:
*/
std::vector<std::string> ListSDLSinkDevices(bool capture);
+/**
+ * Get the reported latency for this sink.
+ *
+ * @return Minimum latency for this sink.
+ */
+u32 GetSDLLatency();
+
} // namespace AudioCore::Sink
diff --git a/src/audio_core/sink/sink_details.cpp b/src/audio_core/sink/sink_details.cpp
index 67bdab779..39ea6d91b 100644
--- a/src/audio_core/sink/sink_details.cpp
+++ b/src/audio_core/sink/sink_details.cpp
@@ -21,58 +21,80 @@ namespace {
struct SinkDetails {
using FactoryFn = std::unique_ptr<Sink> (*)(std::string_view);
using ListDevicesFn = std::vector<std::string> (*)(bool);
+ using LatencyFn = u32 (*)();
/// Name for this sink.
- const char* id;
+ std::string_view id;
/// A method to call to construct an instance of this type of sink.
FactoryFn factory;
/// A method to call to list available devices.
ListDevicesFn list_devices;
+ /// Method to get the latency of this backend.
+ LatencyFn latency;
};
// sink_details is ordered in terms of desirability, with the best choice at the top.
constexpr SinkDetails sink_details[] = {
#ifdef HAVE_CUBEB
- SinkDetails{"cubeb",
- [](std::string_view device_id) -> std::unique_ptr<Sink> {
- return std::make_unique<CubebSink>(device_id);
- },
- &ListCubebSinkDevices},
+ SinkDetails{
+ "cubeb",
+ [](std::string_view device_id) -> std::unique_ptr<Sink> {
+ return std::make_unique<CubebSink>(device_id);
+ },
+ &ListCubebSinkDevices,
+ &GetCubebLatency,
+ },
#endif
#ifdef HAVE_SDL2
- SinkDetails{"sdl2",
- [](std::string_view device_id) -> std::unique_ptr<Sink> {
- return std::make_unique<SDLSink>(device_id);
- },
- &ListSDLSinkDevices},
+ SinkDetails{
+ "sdl2",
+ [](std::string_view device_id) -> std::unique_ptr<Sink> {
+ return std::make_unique<SDLSink>(device_id);
+ },
+ &ListSDLSinkDevices,
+ &GetSDLLatency,
+ },
#endif
SinkDetails{"null",
[](std::string_view device_id) -> std::unique_ptr<Sink> {
return std::make_unique<NullSink>(device_id);
},
- [](bool capture) { return std::vector<std::string>{"null"}; }},
+ [](bool capture) { return std::vector<std::string>{"null"}; }, []() { return 0u; }},
};
const SinkDetails& GetOutputSinkDetails(std::string_view sink_id) {
- auto iter =
- std::find_if(std::begin(sink_details), std::end(sink_details),
- [sink_id](const auto& sink_detail) { return sink_detail.id == sink_id; });
+ const auto find_backend{[](std::string_view id) {
+ return std::find_if(std::begin(sink_details), std::end(sink_details),
+ [&id](const auto& sink_detail) { return sink_detail.id == id; });
+ }};
- if (sink_id == "auto" || iter == std::end(sink_details)) {
- if (sink_id != "auto") {
- LOG_ERROR(Audio, "Invalid sink_id {}", sink_id);
+ auto iter = find_backend(sink_id);
+
+ if (sink_id == "auto") {
+ // Auto-select a backend. Prefer CubeB, but it may report a large minimum latency which
+ // causes audio issues, in that case go with SDL.
+#if defined(HAVE_CUBEB) && defined(HAVE_SDL2)
+ iter = find_backend("cubeb");
+ if (iter->latency() > TargetSampleCount * 3) {
+ iter = find_backend("sdl2");
}
- // Auto-select.
- // sink_details is ordered in terms of desirability, with the best choice at the front.
+#else
iter = std::begin(sink_details);
+#endif
+ LOG_INFO(Service_Audio, "Auto-selecting the {} backend", iter->id);
+ }
+
+ if (iter == std::end(sink_details)) {
+ LOG_ERROR(Audio, "Invalid sink_id {}", sink_id);
+ iter = find_backend("null");
}
return *iter;
}
} // Anonymous namespace
-std::vector<const char*> GetSinkIDs() {
- std::vector<const char*> sink_ids(std::size(sink_details));
+std::vector<std::string_view> GetSinkIDs() {
+ std::vector<std::string_view> sink_ids(std::size(sink_details));
std::transform(std::begin(sink_details), std::end(sink_details), std::begin(sink_ids),
[](const auto& sink) { return sink.id; });
diff --git a/src/audio_core/sink/sink_details.h b/src/audio_core/sink/sink_details.h
index 3ebdb1e30..e75932898 100644
--- a/src/audio_core/sink/sink_details.h
+++ b/src/audio_core/sink/sink_details.h
@@ -19,7 +19,7 @@ class Sink;
*
* @return Vector of available sink names.
*/
-std::vector<const char*> GetSinkIDs();
+std::vector<std::string_view> GetSinkIDs();
/**
* Gets the list of devices for a particular sink identified by the given ID.
diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp
index 37fe725e4..849f862b0 100644
--- a/src/audio_core/sink/sink_stream.cpp
+++ b/src/audio_core/sink/sink_stream.cpp
@@ -214,8 +214,13 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz
// video play out without attempting to stall.
// Can hopefully remove this later with a more complete NVDEC implementation.
const auto nvdec_active{system.AudioCore().IsNVDECActive()};
- if (!nvdec_active && queued_buffers > max_queue_size) {
+
+ // Core timing cannot be paused in single-core mode, so Stall ends up being called over and over
+ // and never recovers to a normal state, so just skip attempting to sync things on single-core.
+ if (system.IsMulticore() && !nvdec_active && queued_buffers > max_queue_size) {
Stall();
+ } else if (system.IsMulticore() && queued_buffers <= max_queue_size) {
+ Unstall();
}
while (frames_written < num_frames) {
@@ -255,7 +260,7 @@ void SinkStream::ProcessAudioOutAndRender(std::span<s16> output_buffer, std::siz
std::memcpy(&last_frame[0], &output_buffer[(frames_written - 1) * frame_size],
frame_size_bytes);
- if (stalled && queued_buffers <= max_queue_size) {
+ if (system.IsMulticore() && queued_buffers <= max_queue_size) {
Unstall();
}
}
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 68436a4bc..c0555f840 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -14,34 +14,11 @@ if (DEFINED ENV{DISPLAYVERSION})
set(DISPLAY_VERSION $ENV{DISPLAYVERSION})
endif ()
-# Pass the path to git to the GenerateSCMRev.cmake as well
-find_package(Git QUIET)
-
-add_custom_command(OUTPUT scm_rev.cpp
- COMMAND ${CMAKE_COMMAND}
- -DSRC_DIR=${PROJECT_SOURCE_DIR}
- -DBUILD_REPOSITORY=${BUILD_REPOSITORY}
- -DTITLE_BAR_FORMAT_IDLE=${TITLE_BAR_FORMAT_IDLE}
- -DTITLE_BAR_FORMAT_RUNNING=${TITLE_BAR_FORMAT_RUNNING}
- -DBUILD_TAG=${BUILD_TAG}
- -DBUILD_ID=${DISPLAY_VERSION}
- -DGIT_REF_SPEC=${GIT_REF_SPEC}
- -DGIT_REV=${GIT_REV}
- -DGIT_DESC=${GIT_DESC}
- -DGIT_BRANCH=${GIT_BRANCH}
- -DBUILD_FULLNAME=${BUILD_FULLNAME}
- -DGIT_EXECUTABLE=${GIT_EXECUTABLE}
- -P ${PROJECT_SOURCE_DIR}/CMakeModules/GenerateSCMRev.cmake
- DEPENDS
- # Check that the scm_rev files haven't changed
- "${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp.in"
- "${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.h"
- # technically we should regenerate if the git version changed, but its not worth the effort imo
- "${PROJECT_SOURCE_DIR}/CMakeModules/GenerateSCMRev.cmake"
- VERBATIM
-)
+include(GenerateSCMRev)
add_library(common STATIC
+ address_space.cpp
+ address_space.h
algorithm.h
alignment.h
announce_multiplayer_room.h
@@ -106,6 +83,8 @@ add_library(common STATIC
microprofile.cpp
microprofile.h
microprofileui.h
+ multi_level_page_table.cpp
+ multi_level_page_table.h
nvidia_flags.cpp
nvidia_flags.h
page_table.cpp
@@ -117,7 +96,7 @@ add_library(common STATIC
quaternion.h
reader_writer_queue.h
ring_buffer.h
- scm_rev.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/scm_rev.cpp
scm_rev.h
scope_exit.h
settings.cpp
@@ -177,12 +156,13 @@ if (MSVC)
)
target_compile_options(common PRIVATE
/W4
- /WX
+
+ /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data
+ /we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
+ /we4800 # Implicit conversion from 'type' to bool. Possible information loss
)
else()
target_compile_options(common PRIVATE
- -Werror
-
$<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>
)
endif()
@@ -190,7 +170,11 @@ endif()
create_target_directory_groups(common)
target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile Threads::Threads)
-target_link_libraries(common PRIVATE lz4::lz4)
+if (TARGET lz4::lz4)
+ target_link_libraries(common PRIVATE lz4::lz4)
+else()
+ target_link_libraries(common PRIVATE LZ4::lz4_shared)
+endif()
if (TARGET zstd::zstd)
target_link_libraries(common PRIVATE zstd::zstd)
else()
diff --git a/src/common/address_space.cpp b/src/common/address_space.cpp
new file mode 100644
index 000000000..866e78dbe
--- /dev/null
+++ b/src/common/address_space.cpp
@@ -0,0 +1,10 @@
+// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "common/address_space.inc"
+
+namespace Common {
+
+template class Common::FlatAllocator<u32, 0, 32>;
+
+}
diff --git a/src/common/address_space.h b/src/common/address_space.h
new file mode 100644
index 000000000..9222b2fdc
--- /dev/null
+++ b/src/common/address_space.h
@@ -0,0 +1,150 @@
+// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <concepts>
+#include <functional>
+#include <mutex>
+#include <vector>
+
+#include "common/common_types.h"
+
+namespace Common {
+template <typename VaType, size_t AddressSpaceBits>
+concept AddressSpaceValid = std::is_unsigned_v<VaType> && sizeof(VaType) * 8 >= AddressSpaceBits;
+
+struct EmptyStruct {};
+
+/**
+ * @brief FlatAddressSpaceMap provides a generic VA->PA mapping implementation using a sorted vector
+ */
+template <typename VaType, VaType UnmappedVa, typename PaType, PaType UnmappedPa,
+ bool PaContigSplit, size_t AddressSpaceBits, typename ExtraBlockInfo = EmptyStruct>
+requires AddressSpaceValid<VaType, AddressSpaceBits>
+class FlatAddressSpaceMap {
+public:
+ /// The maximum VA that this AS can technically reach
+ static constexpr VaType VaMaximum{(1ULL << (AddressSpaceBits - 1)) +
+ ((1ULL << (AddressSpaceBits - 1)) - 1)};
+
+ explicit FlatAddressSpaceMap(VaType va_limit,
+ std::function<void(VaType, VaType)> unmap_callback = {});
+
+ FlatAddressSpaceMap() = default;
+
+ void Map(VaType virt, PaType phys, VaType size, ExtraBlockInfo extra_info = {}) {
+ std::scoped_lock lock(block_mutex);
+ MapLocked(virt, phys, size, extra_info);
+ }
+
+ void Unmap(VaType virt, VaType size) {
+ std::scoped_lock lock(block_mutex);
+ UnmapLocked(virt, size);
+ }
+
+ VaType GetVALimit() const {
+ return va_limit;
+ }
+
+protected:
+ /**
+ * @brief Represents a block of memory in the AS, the physical mapping is contiguous until
+ * another block with a different phys address is hit
+ */
+ struct Block {
+ /// VA of the block
+ VaType virt{UnmappedVa};
+ /// PA of the block, will increase 1-1 with VA until a new block is encountered
+ PaType phys{UnmappedPa};
+ [[no_unique_address]] ExtraBlockInfo extra_info;
+
+ Block() = default;
+
+ Block(VaType virt_, PaType phys_, ExtraBlockInfo extra_info_)
+ : virt(virt_), phys(phys_), extra_info(extra_info_) {}
+
+ bool Valid() const {
+ return virt != UnmappedVa;
+ }
+
+ bool Mapped() const {
+ return phys != UnmappedPa;
+ }
+
+ bool Unmapped() const {
+ return phys == UnmappedPa;
+ }
+
+ bool operator<(const VaType& p_virt) const {
+ return virt < p_virt;
+ }
+ };
+
+ /**
+ * @brief Maps a PA range into the given AS region
+ * @note block_mutex MUST be locked when calling this
+ */
+ void MapLocked(VaType virt, PaType phys, VaType size, ExtraBlockInfo extra_info);
+
+ /**
+ * @brief Unmaps the given range and merges it with other unmapped regions
+ * @note block_mutex MUST be locked when calling this
+ */
+ void UnmapLocked(VaType virt, VaType size);
+
+ std::mutex block_mutex;
+ std::vector<Block> blocks{Block{}};
+
+ /// a soft limit on the maximum VA of the AS
+ VaType va_limit{VaMaximum};
+
+private:
+ /// Callback called when the mappings in an region have changed
+ std::function<void(VaType, VaType)> unmap_callback{};
+};
+
+/**
+ * @brief FlatMemoryManager specialises FlatAddressSpaceMap to work as an allocator, with an
+ * initial, fast linear pass and a subsequent slower pass that iterates until it finds a free block
+ */
+template <typename VaType, VaType UnmappedVa, size_t AddressSpaceBits>
+requires AddressSpaceValid<VaType, AddressSpaceBits>
+class FlatAllocator
+ : public FlatAddressSpaceMap<VaType, UnmappedVa, bool, false, false, AddressSpaceBits> {
+private:
+ using Base = FlatAddressSpaceMap<VaType, UnmappedVa, bool, false, false, AddressSpaceBits>;
+
+public:
+ explicit FlatAllocator(VaType virt_start, VaType va_limit = Base::VaMaximum);
+
+ /**
+ * @brief Allocates a region in the AS of the given size and returns its address
+ */
+ VaType Allocate(VaType size);
+
+ /**
+ * @brief Marks the given region in the AS as allocated
+ */
+ void AllocateFixed(VaType virt, VaType size);
+
+ /**
+ * @brief Frees an AS region so it can be used again
+ */
+ void Free(VaType virt, VaType size);
+
+ VaType GetVAStart() const {
+ return virt_start;
+ }
+
+private:
+ /// The base VA of the allocator, no allocations will be below this
+ VaType virt_start;
+
+ /**
+ * The end address for the initial linear allocation pass
+ * Once this reaches the AS limit the slower allocation path will be used
+ */
+ VaType current_linear_alloc_end;
+};
+} // namespace Common
diff --git a/src/common/address_space.inc b/src/common/address_space.inc
new file mode 100644
index 000000000..2195dabd5
--- /dev/null
+++ b/src/common/address_space.inc
@@ -0,0 +1,366 @@
+// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "common/address_space.h"
+#include "common/assert.h"
+
+#define MAP_MEMBER(returnType) \
+ template <typename VaType, VaType UnmappedVa, typename PaType, PaType UnmappedPa, \
+ bool PaContigSplit, size_t AddressSpaceBits, typename ExtraBlockInfo> \
+ requires AddressSpaceValid<VaType, AddressSpaceBits> returnType FlatAddressSpaceMap< \
+ VaType, UnmappedVa, PaType, UnmappedPa, PaContigSplit, AddressSpaceBits, ExtraBlockInfo>
+#define MAP_MEMBER_CONST() \
+ template <typename VaType, VaType UnmappedVa, typename PaType, PaType UnmappedPa, \
+ bool PaContigSplit, size_t AddressSpaceBits, typename ExtraBlockInfo> \
+ requires AddressSpaceValid<VaType, AddressSpaceBits> FlatAddressSpaceMap< \
+ VaType, UnmappedVa, PaType, UnmappedPa, PaContigSplit, AddressSpaceBits, ExtraBlockInfo>
+
+#define MM_MEMBER(returnType) \
+ template <typename VaType, VaType UnmappedVa, size_t AddressSpaceBits> \
+ requires AddressSpaceValid<VaType, AddressSpaceBits> returnType \
+ FlatMemoryManager<VaType, UnmappedVa, AddressSpaceBits>
+
+#define ALLOC_MEMBER(returnType) \
+ template <typename VaType, VaType UnmappedVa, size_t AddressSpaceBits> \
+ requires AddressSpaceValid<VaType, AddressSpaceBits> returnType \
+ FlatAllocator<VaType, UnmappedVa, AddressSpaceBits>
+#define ALLOC_MEMBER_CONST() \
+ template <typename VaType, VaType UnmappedVa, size_t AddressSpaceBits> \
+ requires AddressSpaceValid<VaType, AddressSpaceBits> \
+ FlatAllocator<VaType, UnmappedVa, AddressSpaceBits>
+
+namespace Common {
+MAP_MEMBER_CONST()::FlatAddressSpaceMap(VaType va_limit_,
+ std::function<void(VaType, VaType)> unmap_callback_)
+ : va_limit{va_limit_}, unmap_callback{std::move(unmap_callback_)} {
+ if (va_limit > VaMaximum) {
+ ASSERT_MSG(false, "Invalid VA limit!");
+ }
+}
+
+MAP_MEMBER(void)::MapLocked(VaType virt, PaType phys, VaType size, ExtraBlockInfo extra_info) {
+ VaType virt_end{virt + size};
+
+ if (virt_end > va_limit) {
+ ASSERT_MSG(false,
+ "Trying to map a block past the VA limit: virt_end: 0x{:X}, va_limit: 0x{:X}",
+ virt_end, va_limit);
+ }
+
+ auto block_end_successor{std::lower_bound(blocks.begin(), blocks.end(), virt_end)};
+ if (block_end_successor == blocks.begin()) {
+ ASSERT_MSG(false, "Trying to map a block before the VA start: virt_end: 0x{:X}", virt_end);
+ }
+
+ auto block_end_predecessor{std::prev(block_end_successor)};
+
+ if (block_end_successor != blocks.end()) {
+ // We have blocks in front of us, if one is directly in front then we don't have to add a
+ // tail
+ if (block_end_successor->virt != virt_end) {
+ PaType tailPhys{[&]() -> PaType {
+ if constexpr (!PaContigSplit) {
+ // Always propagate unmapped regions rather than calculating offset
+ return block_end_predecessor->phys;
+ } else {
+ if (block_end_predecessor->Unmapped()) {
+ // Always propagate unmapped regions rather than calculating offset
+ return block_end_predecessor->phys;
+ } else {
+ return block_end_predecessor->phys + virt_end - block_end_predecessor->virt;
+ }
+ }
+ }()};
+
+ if (block_end_predecessor->virt >= virt) {
+ // If this block's start would be overlapped by the map then reuse it as a tail
+ // block
+ block_end_predecessor->virt = virt_end;
+ block_end_predecessor->phys = tailPhys;
+ block_end_predecessor->extra_info = block_end_predecessor->extra_info;
+
+ // No longer predecessor anymore
+ block_end_successor = block_end_predecessor--;
+ } else {
+ // Else insert a new one and we're done
+ blocks.insert(block_end_successor,
+ {Block(virt, phys, extra_info),
+ Block(virt_end, tailPhys, block_end_predecessor->extra_info)});
+ if (unmap_callback) {
+ unmap_callback(virt, size);
+ }
+
+ return;
+ }
+ }
+ } else {
+ // block_end_predecessor will always be unmapped as blocks has to be terminated by an
+ // unmapped chunk
+ if (block_end_predecessor != blocks.begin() && block_end_predecessor->virt >= virt) {
+ // Move the unmapped block start backwards
+ block_end_predecessor->virt = virt_end;
+
+ // No longer predecessor anymore
+ block_end_successor = block_end_predecessor--;
+ } else {
+ // Else insert a new one and we're done
+ blocks.insert(block_end_successor,
+ {Block(virt, phys, extra_info), Block(virt_end, UnmappedPa, {})});
+ if (unmap_callback) {
+ unmap_callback(virt, size);
+ }
+
+ return;
+ }
+ }
+
+ auto block_start_successor{block_end_successor};
+
+ // Walk the block vector to find the start successor as this is more efficient than another
+ // binary search in most scenarios
+ while (std::prev(block_start_successor)->virt >= virt) {
+ block_start_successor--;
+ }
+
+ // Check that the start successor is either the end block or something in between
+ if (block_start_successor->virt > virt_end) {
+ ASSERT_MSG(false, "Unsorted block in AS map: virt: 0x{:X}", block_start_successor->virt);
+ } else if (block_start_successor->virt == virt_end) {
+ // We need to create a new block as there are none spare that we would overwrite
+ blocks.insert(block_start_successor, Block(virt, phys, extra_info));
+ } else {
+ // Erase overwritten blocks
+ if (auto eraseStart{std::next(block_start_successor)}; eraseStart != block_end_successor) {
+ blocks.erase(eraseStart, block_end_successor);
+ }
+
+ // Reuse a block that would otherwise be overwritten as a start block
+ block_start_successor->virt = virt;
+ block_start_successor->phys = phys;
+ block_start_successor->extra_info = extra_info;
+ }
+
+ if (unmap_callback) {
+ unmap_callback(virt, size);
+ }
+}
+
+MAP_MEMBER(void)::UnmapLocked(VaType virt, VaType size) {
+ VaType virt_end{virt + size};
+
+ if (virt_end > va_limit) {
+ ASSERT_MSG(false,
+ "Trying to map a block past the VA limit: virt_end: 0x{:X}, va_limit: 0x{:X}",
+ virt_end, va_limit);
+ }
+
+ auto block_end_successor{std::lower_bound(blocks.begin(), blocks.end(), virt_end)};
+ if (block_end_successor == blocks.begin()) {
+ ASSERT_MSG(false, "Trying to unmap a block before the VA start: virt_end: 0x{:X}",
+ virt_end);
+ }
+
+ auto block_end_predecessor{std::prev(block_end_successor)};
+
+ auto walk_back_to_predecessor{[&](auto iter) {
+ while (iter->virt >= virt) {
+ iter--;
+ }
+
+ return iter;
+ }};
+
+ auto erase_blocks_with_end_unmapped{[&](auto unmappedEnd) {
+ auto block_start_predecessor{walk_back_to_predecessor(unmappedEnd)};
+ auto block_start_successor{std::next(block_start_predecessor)};
+
+ auto eraseEnd{[&]() {
+ if (block_start_predecessor->Unmapped()) {
+ // If the start predecessor is unmapped then we can erase everything in our region
+ // and be done
+ return std::next(unmappedEnd);
+ } else {
+ // Else reuse the end predecessor as the start of our unmapped region then erase all
+ // up to it
+ unmappedEnd->virt = virt;
+ return unmappedEnd;
+ }
+ }()};
+
+ // We can't have two unmapped regions after each other
+ if (eraseEnd != blocks.end() &&
+ (eraseEnd == block_start_successor ||
+ (block_start_predecessor->Unmapped() && eraseEnd->Unmapped()))) {
+ ASSERT_MSG(false, "Multiple contiguous unmapped regions are unsupported!");
+ }
+
+ blocks.erase(block_start_successor, eraseEnd);
+ }};
+
+ // We can avoid any splitting logic if these are the case
+ if (block_end_predecessor->Unmapped()) {
+ if (block_end_predecessor->virt > virt) {
+ erase_blocks_with_end_unmapped(block_end_predecessor);
+ }
+
+ if (unmap_callback) {
+ unmap_callback(virt, size);
+ }
+
+ return; // The region is unmapped, bail out early
+ } else if (block_end_successor->virt == virt_end && block_end_successor->Unmapped()) {
+ erase_blocks_with_end_unmapped(block_end_successor);
+
+ if (unmap_callback) {
+ unmap_callback(virt, size);
+ }
+
+ return; // The region is unmapped here and doesn't need splitting, bail out early
+ } else if (block_end_successor == blocks.end()) {
+ // This should never happen as the end should always follow an unmapped block
+ ASSERT_MSG(false, "Unexpected Memory Manager state!");
+ } else if (block_end_successor->virt != virt_end) {
+ // If one block is directly in front then we don't have to add a tail
+
+ // The previous block is mapped so we will need to add a tail with an offset
+ PaType tailPhys{[&]() {
+ if constexpr (PaContigSplit) {
+ return block_end_predecessor->phys + virt_end - block_end_predecessor->virt;
+ } else {
+ return block_end_predecessor->phys;
+ }
+ }()};
+
+ if (block_end_predecessor->virt >= virt) {
+ // If this block's start would be overlapped by the unmap then reuse it as a tail block
+ block_end_predecessor->virt = virt_end;
+ block_end_predecessor->phys = tailPhys;
+
+ // No longer predecessor anymore
+ block_end_successor = block_end_predecessor--;
+ } else {
+ blocks.insert(block_end_successor,
+ {Block(virt, UnmappedPa, {}),
+ Block(virt_end, tailPhys, block_end_predecessor->extra_info)});
+ if (unmap_callback) {
+ unmap_callback(virt, size);
+ }
+
+ // The previous block is mapped and ends before
+ return;
+ }
+ }
+
+ // Walk the block vector to find the start predecessor as this is more efficient than another
+ // binary search in most scenarios
+ auto block_start_predecessor{walk_back_to_predecessor(block_end_successor)};
+ auto block_start_successor{std::next(block_start_predecessor)};
+
+ if (block_start_successor->virt > virt_end) {
+ ASSERT_MSG(false, "Unsorted block in AS map: virt: 0x{:X}", block_start_successor->virt);
+ } else if (block_start_successor->virt == virt_end) {
+ // There are no blocks between the start and the end that would let us skip inserting a new
+ // one for head
+
+ // The previous block is may be unmapped, if so we don't need to insert any unmaps after it
+ if (block_start_predecessor->Mapped()) {
+ blocks.insert(block_start_successor, Block(virt, UnmappedPa, {}));
+ }
+ } else if (block_start_predecessor->Unmapped()) {
+ // If the previous block is unmapped
+ blocks.erase(block_start_successor, block_end_predecessor);
+ } else {
+ // Erase overwritten blocks, skipping the first one as we have written the unmapped start
+ // block there
+ if (auto eraseStart{std::next(block_start_successor)}; eraseStart != block_end_successor) {
+ blocks.erase(eraseStart, block_end_successor);
+ }
+
+ // Add in the unmapped block header
+ block_start_successor->virt = virt;
+ block_start_successor->phys = UnmappedPa;
+ }
+
+ if (unmap_callback)
+ unmap_callback(virt, size);
+}
+
+ALLOC_MEMBER_CONST()::FlatAllocator(VaType virt_start_, VaType va_limit_)
+ : Base{va_limit_}, virt_start{virt_start_}, current_linear_alloc_end{virt_start_} {}
+
+ALLOC_MEMBER(VaType)::Allocate(VaType size) {
+ std::scoped_lock lock(this->block_mutex);
+
+ VaType alloc_start{UnmappedVa};
+ VaType alloc_end{current_linear_alloc_end + size};
+
+ // Avoid searching backwards in the address space if possible
+ if (alloc_end >= current_linear_alloc_end && alloc_end <= this->va_limit) {
+ auto alloc_end_successor{
+ std::lower_bound(this->blocks.begin(), this->blocks.end(), alloc_end)};
+ if (alloc_end_successor == this->blocks.begin()) {
+ ASSERT_MSG(false, "First block in AS map is invalid!");
+ }
+
+ auto alloc_end_predecessor{std::prev(alloc_end_successor)};
+ if (alloc_end_predecessor->virt <= current_linear_alloc_end) {
+ alloc_start = current_linear_alloc_end;
+ } else {
+ // Skip over fixed any mappings in front of us
+ while (alloc_end_successor != this->blocks.end()) {
+ if (alloc_end_successor->virt - alloc_end_predecessor->virt < size ||
+ alloc_end_predecessor->Mapped()) {
+ alloc_start = alloc_end_predecessor->virt;
+ break;
+ }
+
+ alloc_end_predecessor = alloc_end_successor++;
+
+ // Use the VA limit to calculate if we can fit in the final block since it has no
+ // successor
+ if (alloc_end_successor == this->blocks.end()) {
+ alloc_end = alloc_end_predecessor->virt + size;
+
+ if (alloc_end >= alloc_end_predecessor->virt && alloc_end <= this->va_limit) {
+ alloc_start = alloc_end_predecessor->virt;
+ }
+ }
+ }
+ }
+ }
+
+ if (alloc_start != UnmappedVa) {
+ current_linear_alloc_end = alloc_start + size;
+ } else { // If linear allocation overflows the AS then find a gap
+ if (this->blocks.size() <= 2) {
+ ASSERT_MSG(false, "Unexpected allocator state!");
+ }
+
+ auto search_predecessor{this->blocks.begin()};
+ auto search_successor{std::next(search_predecessor)};
+
+ while (search_successor != this->blocks.end() &&
+ (search_successor->virt - search_predecessor->virt < size ||
+ search_predecessor->Mapped())) {
+ search_predecessor = search_successor++;
+ }
+
+ if (search_successor != this->blocks.end()) {
+ alloc_start = search_predecessor->virt;
+ } else {
+ return {}; // AS is full
+ }
+ }
+
+ this->MapLocked(alloc_start, true, size, {});
+ return alloc_start;
+}
+
+ALLOC_MEMBER(void)::AllocateFixed(VaType virt, VaType size) {
+ this->Map(virt, true, size);
+}
+
+ALLOC_MEMBER(void)::Free(VaType virt, VaType size) {
+ this->Unmap(virt, size);
+}
+} // namespace Common
diff --git a/src/common/algorithm.h b/src/common/algorithm.h
index 9ddfd637b..c27c9241d 100644
--- a/src/common/algorithm.h
+++ b/src/common/algorithm.h
@@ -24,4 +24,12 @@ template <class ForwardIt, class T, class Compare = std::less<>>
return first != last && !comp(value, *first) ? first : last;
}
+template <typename T, typename Func, typename... Args>
+T FoldRight(T initial_value, Func&& func, Args&&... args) {
+ T value{initial_value};
+ const auto high_func = [&value, &func]<typename U>(U x) { value = func(value, x); };
+ (std::invoke(high_func, std::forward<Args>(args)), ...);
+ return value;
+}
+
} // namespace Common
diff --git a/src/common/bit_field.h b/src/common/bit_field.h
index 7e1df62b1..e4e58ea45 100644
--- a/src/common/bit_field.h
+++ b/src/common/bit_field.h
@@ -141,10 +141,6 @@ public:
constexpr BitField(BitField&&) noexcept = default;
constexpr BitField& operator=(BitField&&) noexcept = default;
- [[nodiscard]] constexpr operator T() const {
- return Value();
- }
-
constexpr void Assign(const T& value) {
#ifdef _MSC_VER
storage = static_cast<StorageType>((storage & ~mask) | FormatValue(value));
@@ -162,6 +158,17 @@ public:
return ExtractValue(storage);
}
+ template <typename ConvertedToType>
+ [[nodiscard]] constexpr ConvertedToType As() const {
+ static_assert(!std::is_same_v<T, ConvertedToType>,
+ "Unnecessary cast. Use Value() instead.");
+ return static_cast<ConvertedToType>(Value());
+ }
+
+ [[nodiscard]] constexpr operator T() const {
+ return Value();
+ }
+
[[nodiscard]] constexpr explicit operator bool() const {
return Value() != 0;
}
diff --git a/src/common/bounded_threadsafe_queue.h b/src/common/bounded_threadsafe_queue.h
index 7e465549b..21217801e 100644
--- a/src/common/bounded_threadsafe_queue.h
+++ b/src/common/bounded_threadsafe_queue.h
@@ -21,11 +21,6 @@ constexpr size_t hardware_interference_size = std::hardware_destructive_interfer
constexpr size_t hardware_interference_size = 64;
#endif
-#ifdef _MSC_VER
-#pragma warning(push)
-#pragma warning(disable : 4324)
-#endif
-
template <typename T, size_t capacity = 0x400>
class MPSCQueue {
public:
@@ -160,8 +155,4 @@ private:
static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible");
};
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
} // namespace Common
diff --git a/src/common/concepts.h b/src/common/concepts.h
index a97555f6a..a9acff3e7 100644
--- a/src/common/concepts.h
+++ b/src/common/concepts.h
@@ -3,24 +3,14 @@
#pragma once
+#include <iterator>
#include <type_traits>
namespace Common {
-// Check if type is like an STL container
+// Check if type satisfies the ContiguousContainer named requirement.
template <typename T>
-concept IsSTLContainer = requires(T t) {
- typename T::value_type;
- typename T::iterator;
- typename T::const_iterator;
- // TODO(ogniK): Replace below is std::same_as<void> when MSVC supports it.
- t.begin();
- t.end();
- t.cbegin();
- t.cend();
- t.data();
- t.size();
-};
+concept IsContiguousContainer = std::contiguous_iterator<typename T::iterator>;
// TODO: Replace with std::derived_from when the <concepts> header
// is available on all supported platforms.
@@ -34,4 +24,12 @@ concept DerivedFrom = requires {
template <typename From, typename To>
concept ConvertibleTo = std::is_convertible_v<From, To>;
+// No equivalents in the stdlib
+
+template <typename T>
+concept IsArithmetic = std::is_arithmetic_v<T>;
+
+template <typename T>
+concept IsIntegral = std::is_integral_v<T>;
+
} // namespace Common
diff --git a/src/common/fixed_point.h b/src/common/fixed_point.h
index 4a0f72cc9..f899b0d54 100644
--- a/src/common/fixed_point.h
+++ b/src/common/fixed_point.h
@@ -4,14 +4,7 @@
// From: https://github.com/eteran/cpp-utilities/blob/master/fixed/include/cpp-utilities/fixed.h
// See also: http://stackoverflow.com/questions/79677/whats-the-best-way-to-do-fixed-point-math
-#ifndef FIXED_H_
-#define FIXED_H_
-
-#if __cplusplus >= 201402L
-#define CONSTEXPR14 constexpr
-#else
-#define CONSTEXPR14
-#endif
+#pragma once
#include <cstddef> // for size_t
#include <cstdint>
@@ -19,6 +12,8 @@
#include <ostream>
#include <type_traits>
+#include <common/concepts.h>
+
namespace Common {
template <size_t I, size_t F>
@@ -57,8 +52,8 @@ struct type_from_size<64> {
static constexpr size_t size = 64;
using value_type = int64_t;
- using unsigned_type = std::make_unsigned<value_type>::type;
- using signed_type = std::make_signed<value_type>::type;
+ using unsigned_type = std::make_unsigned_t<value_type>;
+ using signed_type = std::make_signed_t<value_type>;
using next_size = type_from_size<128>;
};
@@ -68,8 +63,8 @@ struct type_from_size<32> {
static constexpr size_t size = 32;
using value_type = int32_t;
- using unsigned_type = std::make_unsigned<value_type>::type;
- using signed_type = std::make_signed<value_type>::type;
+ using unsigned_type = std::make_unsigned_t<value_type>;
+ using signed_type = std::make_signed_t<value_type>;
using next_size = type_from_size<64>;
};
@@ -79,8 +74,8 @@ struct type_from_size<16> {
static constexpr size_t size = 16;
using value_type = int16_t;
- using unsigned_type = std::make_unsigned<value_type>::type;
- using signed_type = std::make_signed<value_type>::type;
+ using unsigned_type = std::make_unsigned_t<value_type>;
+ using signed_type = std::make_signed_t<value_type>;
using next_size = type_from_size<32>;
};
@@ -90,8 +85,8 @@ struct type_from_size<8> {
static constexpr size_t size = 8;
using value_type = int8_t;
- using unsigned_type = std::make_unsigned<value_type>::type;
- using signed_type = std::make_signed<value_type>::type;
+ using unsigned_type = std::make_unsigned_t<value_type>;
+ using signed_type = std::make_signed_t<value_type>;
using next_size = type_from_size<16>;
};
@@ -106,9 +101,9 @@ constexpr B next_to_base(N rhs) {
struct divide_by_zero : std::exception {};
template <size_t I, size_t F>
-CONSTEXPR14 FixedPoint<I, F> divide(
+constexpr FixedPoint<I, F> divide(
FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder,
- typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
+ std::enable_if_t<type_from_size<I + F>::next_size::is_specialized>* = nullptr) {
using next_type = typename FixedPoint<I, F>::next_type;
using base_type = typename FixedPoint<I, F>::base_type;
@@ -126,9 +121,9 @@ CONSTEXPR14 FixedPoint<I, F> divide(
}
template <size_t I, size_t F>
-CONSTEXPR14 FixedPoint<I, F> divide(
+constexpr FixedPoint<I, F> divide(
FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder,
- typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
+ std::enable_if_t<!type_from_size<I + F>::next_size::is_specialized>* = nullptr) {
using unsigned_type = typename FixedPoint<I, F>::unsigned_type;
@@ -196,9 +191,9 @@ CONSTEXPR14 FixedPoint<I, F> divide(
// this is the usual implementation of multiplication
template <size_t I, size_t F>
-CONSTEXPR14 FixedPoint<I, F> multiply(
+constexpr FixedPoint<I, F> multiply(
FixedPoint<I, F> lhs, FixedPoint<I, F> rhs,
- typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
+ std::enable_if_t<type_from_size<I + F>::next_size::is_specialized>* = nullptr) {
using next_type = typename FixedPoint<I, F>::next_type;
using base_type = typename FixedPoint<I, F>::base_type;
@@ -215,9 +210,9 @@ CONSTEXPR14 FixedPoint<I, F> multiply(
// it is slightly slower, but is more robust since it doesn't
// require and upgraded type
template <size_t I, size_t F>
-CONSTEXPR14 FixedPoint<I, F> multiply(
+constexpr FixedPoint<I, F> multiply(
FixedPoint<I, F> lhs, FixedPoint<I, F> rhs,
- typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
+ std::enable_if_t<!type_from_size<I + F>::next_size::is_specialized>* = nullptr) {
using base_type = typename FixedPoint<I, F>::base_type;
@@ -272,19 +267,20 @@ public:
static constexpr base_type one = base_type(1) << fractional_bits;
public: // constructors
- FixedPoint() = default;
- FixedPoint(const FixedPoint&) = default;
- FixedPoint(FixedPoint&&) = default;
- FixedPoint& operator=(const FixedPoint&) = default;
+ constexpr FixedPoint() = default;
+
+ constexpr FixedPoint(const FixedPoint&) = default;
+ constexpr FixedPoint& operator=(const FixedPoint&) = default;
+
+ constexpr FixedPoint(FixedPoint&&) noexcept = default;
+ constexpr FixedPoint& operator=(FixedPoint&&) noexcept = default;
- template <class Number>
- constexpr FixedPoint(
- Number n, typename std::enable_if<std::is_arithmetic<Number>::value>::type* = nullptr)
- : data_(static_cast<base_type>(n * one)) {}
+ template <IsArithmetic Number>
+ constexpr FixedPoint(Number n) : data_(static_cast<base_type>(n * one)) {}
public: // conversion
template <size_t I2, size_t F2>
- CONSTEXPR14 explicit FixedPoint(FixedPoint<I2, F2> other) {
+ constexpr explicit FixedPoint(FixedPoint<I2, F2> other) {
static_assert(I2 <= I && F2 <= F, "Scaling conversion can only upgrade types");
using T = FixedPoint<I2, F2>;
@@ -308,36 +304,14 @@ public:
}
public: // comparison operators
- constexpr bool operator==(FixedPoint rhs) const {
- return data_ == rhs.data_;
- }
-
- constexpr bool operator!=(FixedPoint rhs) const {
- return data_ != rhs.data_;
- }
-
- constexpr bool operator<(FixedPoint rhs) const {
- return data_ < rhs.data_;
- }
-
- constexpr bool operator>(FixedPoint rhs) const {
- return data_ > rhs.data_;
- }
-
- constexpr bool operator<=(FixedPoint rhs) const {
- return data_ <= rhs.data_;
- }
-
- constexpr bool operator>=(FixedPoint rhs) const {
- return data_ >= rhs.data_;
- }
+ friend constexpr auto operator<=>(FixedPoint lhs, FixedPoint rhs) = default;
public: // unary operators
- constexpr bool operator!() const {
+ [[nodiscard]] constexpr bool operator!() const {
return !data_;
}
- constexpr FixedPoint operator~() const {
+ [[nodiscard]] constexpr FixedPoint operator~() const {
// NOTE(eteran): this will often appear to "just negate" the value
// that is not an error, it is because -x == (~x+1)
// and that "+1" is adding an infinitesimally small fraction to the
@@ -345,89 +319,87 @@ public: // unary operators
return FixedPoint::from_base(~data_);
}
- constexpr FixedPoint operator-() const {
+ [[nodiscard]] constexpr FixedPoint operator-() const {
return FixedPoint::from_base(-data_);
}
- constexpr FixedPoint operator+() const {
+ [[nodiscard]] constexpr FixedPoint operator+() const {
return FixedPoint::from_base(+data_);
}
- CONSTEXPR14 FixedPoint& operator++() {
+ constexpr FixedPoint& operator++() {
data_ += one;
return *this;
}
- CONSTEXPR14 FixedPoint& operator--() {
+ constexpr FixedPoint& operator--() {
data_ -= one;
return *this;
}
- CONSTEXPR14 FixedPoint operator++(int) {
+ constexpr FixedPoint operator++(int) {
FixedPoint tmp(*this);
data_ += one;
return tmp;
}
- CONSTEXPR14 FixedPoint operator--(int) {
+ constexpr FixedPoint operator--(int) {
FixedPoint tmp(*this);
data_ -= one;
return tmp;
}
public: // basic math operators
- CONSTEXPR14 FixedPoint& operator+=(FixedPoint n) {
+ constexpr FixedPoint& operator+=(FixedPoint n) {
data_ += n.data_;
return *this;
}
- CONSTEXPR14 FixedPoint& operator-=(FixedPoint n) {
+ constexpr FixedPoint& operator-=(FixedPoint n) {
data_ -= n.data_;
return *this;
}
- CONSTEXPR14 FixedPoint& operator*=(FixedPoint n) {
+ constexpr FixedPoint& operator*=(FixedPoint n) {
return assign(detail::multiply(*this, n));
}
- CONSTEXPR14 FixedPoint& operator/=(FixedPoint n) {
+ constexpr FixedPoint& operator/=(FixedPoint n) {
FixedPoint temp;
return assign(detail::divide(*this, n, temp));
}
private:
- CONSTEXPR14 FixedPoint& assign(FixedPoint rhs) {
+ constexpr FixedPoint& assign(FixedPoint rhs) {
data_ = rhs.data_;
return *this;
}
public: // binary math operators, effects underlying bit pattern since these
// don't really typically make sense for non-integer values
- CONSTEXPR14 FixedPoint& operator&=(FixedPoint n) {
+ constexpr FixedPoint& operator&=(FixedPoint n) {
data_ &= n.data_;
return *this;
}
- CONSTEXPR14 FixedPoint& operator|=(FixedPoint n) {
+ constexpr FixedPoint& operator|=(FixedPoint n) {
data_ |= n.data_;
return *this;
}
- CONSTEXPR14 FixedPoint& operator^=(FixedPoint n) {
+ constexpr FixedPoint& operator^=(FixedPoint n) {
data_ ^= n.data_;
return *this;
}
- template <class Integer,
- class = typename std::enable_if<std::is_integral<Integer>::value>::type>
- CONSTEXPR14 FixedPoint& operator>>=(Integer n) {
+ template <IsIntegral Integer>
+ constexpr FixedPoint& operator>>=(Integer n) {
data_ >>= n;
return *this;
}
- template <class Integer,
- class = typename std::enable_if<std::is_integral<Integer>::value>::type>
- CONSTEXPR14 FixedPoint& operator<<=(Integer n) {
+ template <IsIntegral Integer>
+ constexpr FixedPoint& operator<<=(Integer n) {
data_ <<= n;
return *this;
}
@@ -437,42 +409,42 @@ public: // conversion to basic types
data_ += (data_ & fractional_mask) >> 1;
}
- constexpr int to_int() {
+ [[nodiscard]] constexpr int to_int() {
round_up();
return static_cast<int>((data_ & integer_mask) >> fractional_bits);
}
- constexpr unsigned int to_uint() const {
+ [[nodiscard]] constexpr unsigned int to_uint() {
round_up();
return static_cast<unsigned int>((data_ & integer_mask) >> fractional_bits);
}
- constexpr int64_t to_long() {
+ [[nodiscard]] constexpr int64_t to_long() {
round_up();
return static_cast<int64_t>((data_ & integer_mask) >> fractional_bits);
}
- constexpr int to_int_floor() const {
+ [[nodiscard]] constexpr int to_int_floor() const {
return static_cast<int>((data_ & integer_mask) >> fractional_bits);
}
- constexpr int64_t to_long_floor() {
+ [[nodiscard]] constexpr int64_t to_long_floor() const {
return static_cast<int64_t>((data_ & integer_mask) >> fractional_bits);
}
- constexpr unsigned int to_uint_floor() const {
+ [[nodiscard]] constexpr unsigned int to_uint_floor() const {
return static_cast<unsigned int>((data_ & integer_mask) >> fractional_bits);
}
- constexpr float to_float() const {
+ [[nodiscard]] constexpr float to_float() const {
return static_cast<float>(data_) / FixedPoint::one;
}
- constexpr double to_double() const {
+ [[nodiscard]] constexpr double to_double() const {
return static_cast<double>(data_) / FixedPoint::one;
}
- constexpr base_type to_raw() const {
+ [[nodiscard]] constexpr base_type to_raw() const {
return data_;
}
@@ -480,27 +452,27 @@ public: // conversion to basic types
data_ &= fractional_mask;
}
- constexpr base_type get_frac() const {
+ [[nodiscard]] constexpr base_type get_frac() const {
return data_ & fractional_mask;
}
public:
- CONSTEXPR14 void swap(FixedPoint& rhs) {
+ constexpr void swap(FixedPoint& rhs) noexcept {
using std::swap;
swap(data_, rhs.data_);
}
public:
- base_type data_;
+ base_type data_{};
};
// if we have the same fractional portion, but differing integer portions, we trivially upgrade the
// smaller type
template <size_t I1, size_t I2, size_t F>
-CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type
-operator+(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
+constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator+(
+ FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
- using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
+ using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>;
const T l = T::from_base(lhs.to_raw());
const T r = T::from_base(rhs.to_raw());
@@ -508,10 +480,10 @@ operator+(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
}
template <size_t I1, size_t I2, size_t F>
-CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type
-operator-(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
+constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator-(
+ FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
- using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
+ using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>;
const T l = T::from_base(lhs.to_raw());
const T r = T::from_base(rhs.to_raw());
@@ -519,10 +491,10 @@ operator-(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
}
template <size_t I1, size_t I2, size_t F>
-CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type
-operator*(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
+constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator*(
+ FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
- using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
+ using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>;
const T l = T::from_base(lhs.to_raw());
const T r = T::from_base(rhs.to_raw());
@@ -530,10 +502,10 @@ operator*(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
}
template <size_t I1, size_t I2, size_t F>
-CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type
-operator/(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
+constexpr std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>> operator/(
+ FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
- using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
+ using T = std::conditional_t<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>;
const T l = T::from_base(lhs.to_raw());
const T r = T::from_base(rhs.to_raw());
@@ -548,159 +520,133 @@ std::ostream& operator<<(std::ostream& os, FixedPoint<I, F> f) {
// basic math operators
template <size_t I, size_t F>
-CONSTEXPR14 FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
+constexpr FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
lhs += rhs;
return lhs;
}
template <size_t I, size_t F>
-CONSTEXPR14 FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
+constexpr FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
lhs -= rhs;
return lhs;
}
template <size_t I, size_t F>
-CONSTEXPR14 FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
+constexpr FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
lhs *= rhs;
return lhs;
}
template <size_t I, size_t F>
-CONSTEXPR14 FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
+constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
lhs /= rhs;
return lhs;
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
-CONSTEXPR14 FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, Number rhs) {
+template <size_t I, size_t F, IsArithmetic Number>
+constexpr FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, Number rhs) {
lhs += FixedPoint<I, F>(rhs);
return lhs;
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
-CONSTEXPR14 FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, Number rhs) {
+template <size_t I, size_t F, IsArithmetic Number>
+constexpr FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, Number rhs) {
lhs -= FixedPoint<I, F>(rhs);
return lhs;
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
-CONSTEXPR14 FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, Number rhs) {
+template <size_t I, size_t F, IsArithmetic Number>
+constexpr FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, Number rhs) {
lhs *= FixedPoint<I, F>(rhs);
return lhs;
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
-CONSTEXPR14 FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, Number rhs) {
+template <size_t I, size_t F, IsArithmetic Number>
+constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, Number rhs) {
lhs /= FixedPoint<I, F>(rhs);
return lhs;
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
-CONSTEXPR14 FixedPoint<I, F> operator+(Number lhs, FixedPoint<I, F> rhs) {
+template <size_t I, size_t F, IsArithmetic Number>
+constexpr FixedPoint<I, F> operator+(Number lhs, FixedPoint<I, F> rhs) {
FixedPoint<I, F> tmp(lhs);
tmp += rhs;
return tmp;
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
-CONSTEXPR14 FixedPoint<I, F> operator-(Number lhs, FixedPoint<I, F> rhs) {
+template <size_t I, size_t F, IsArithmetic Number>
+constexpr FixedPoint<I, F> operator-(Number lhs, FixedPoint<I, F> rhs) {
FixedPoint<I, F> tmp(lhs);
tmp -= rhs;
return tmp;
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
-CONSTEXPR14 FixedPoint<I, F> operator*(Number lhs, FixedPoint<I, F> rhs) {
+template <size_t I, size_t F, IsArithmetic Number>
+constexpr FixedPoint<I, F> operator*(Number lhs, FixedPoint<I, F> rhs) {
FixedPoint<I, F> tmp(lhs);
tmp *= rhs;
return tmp;
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
-CONSTEXPR14 FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) {
+template <size_t I, size_t F, IsArithmetic Number>
+constexpr FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) {
FixedPoint<I, F> tmp(lhs);
tmp /= rhs;
return tmp;
}
// shift operators
-template <size_t I, size_t F, class Integer,
- class = typename std::enable_if<std::is_integral<Integer>::value>::type>
-CONSTEXPR14 FixedPoint<I, F> operator<<(FixedPoint<I, F> lhs, Integer rhs) {
+template <size_t I, size_t F, IsIntegral Integer>
+constexpr FixedPoint<I, F> operator<<(FixedPoint<I, F> lhs, Integer rhs) {
lhs <<= rhs;
return lhs;
}
-template <size_t I, size_t F, class Integer,
- class = typename std::enable_if<std::is_integral<Integer>::value>::type>
-CONSTEXPR14 FixedPoint<I, F> operator>>(FixedPoint<I, F> lhs, Integer rhs) {
+template <size_t I, size_t F, IsIntegral Integer>
+constexpr FixedPoint<I, F> operator>>(FixedPoint<I, F> lhs, Integer rhs) {
lhs >>= rhs;
return lhs;
}
// comparison operators
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
+template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator>(FixedPoint<I, F> lhs, Number rhs) {
return lhs > FixedPoint<I, F>(rhs);
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
+template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator<(FixedPoint<I, F> lhs, Number rhs) {
return lhs < FixedPoint<I, F>(rhs);
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
+template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator>=(FixedPoint<I, F> lhs, Number rhs) {
return lhs >= FixedPoint<I, F>(rhs);
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
+template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator<=(FixedPoint<I, F> lhs, Number rhs) {
return lhs <= FixedPoint<I, F>(rhs);
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
+template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator==(FixedPoint<I, F> lhs, Number rhs) {
return lhs == FixedPoint<I, F>(rhs);
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
+template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator!=(FixedPoint<I, F> lhs, Number rhs) {
return lhs != FixedPoint<I, F>(rhs);
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
+template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator>(Number lhs, FixedPoint<I, F> rhs) {
return FixedPoint<I, F>(lhs) > rhs;
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
+template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator<(Number lhs, FixedPoint<I, F> rhs) {
return FixedPoint<I, F>(lhs) < rhs;
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
+template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator>=(Number lhs, FixedPoint<I, F> rhs) {
return FixedPoint<I, F>(lhs) >= rhs;
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
+template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator<=(Number lhs, FixedPoint<I, F> rhs) {
return FixedPoint<I, F>(lhs) <= rhs;
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
+template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator==(Number lhs, FixedPoint<I, F> rhs) {
return FixedPoint<I, F>(lhs) == rhs;
}
-template <size_t I, size_t F, class Number,
- class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
+template <size_t I, size_t F, IsArithmetic Number>
constexpr bool operator!=(Number lhs, FixedPoint<I, F> rhs) {
return FixedPoint<I, F>(lhs) != rhs;
}
} // namespace Common
-
-#undef CONSTEXPR14
-
-#endif
diff --git a/src/common/fs/file.h b/src/common/fs/file.h
index 69b53384c..167c4d826 100644
--- a/src/common/fs/file.h
+++ b/src/common/fs/file.h
@@ -209,8 +209,8 @@ public:
/**
* Helper function which deduces the value type of a contiguous STL container used in ReadSpan.
- * If T is not a contiguous STL container as defined by the concept IsSTLContainer, this calls
- * ReadObject and T must be a trivially copyable object.
+ * If T is not a contiguous container as defined by the concept IsContiguousContainer, this
+ * calls ReadObject and T must be a trivially copyable object.
*
* See ReadSpan for more details if T is a contiguous container.
* See ReadObject for more details if T is a trivially copyable object.
@@ -223,7 +223,7 @@ public:
*/
template <typename T>
[[nodiscard]] size_t Read(T& data) const {
- if constexpr (IsSTLContainer<T>) {
+ if constexpr (IsContiguousContainer<T>) {
using ContiguousType = typename T::value_type;
static_assert(std::is_trivially_copyable_v<ContiguousType>,
"Data type must be trivially copyable.");
@@ -235,8 +235,8 @@ public:
/**
* Helper function which deduces the value type of a contiguous STL container used in WriteSpan.
- * If T is not a contiguous STL container as defined by the concept IsSTLContainer, this calls
- * WriteObject and T must be a trivially copyable object.
+ * If T is not a contiguous STL container as defined by the concept IsContiguousContainer, this
+ * calls WriteObject and T must be a trivially copyable object.
*
* See WriteSpan for more details if T is a contiguous container.
* See WriteObject for more details if T is a trivially copyable object.
@@ -249,7 +249,7 @@ public:
*/
template <typename T>
[[nodiscard]] size_t Write(const T& data) const {
- if constexpr (IsSTLContainer<T>) {
+ if constexpr (IsContiguousContainer<T>) {
using ContiguousType = typename T::value_type;
static_assert(std::is_trivially_copyable_v<ContiguousType>,
"Data type must be trivially copyable.");
diff --git a/src/common/hash.h b/src/common/hash.h
index b6f3e6d6f..e8fe78b07 100644
--- a/src/common/hash.h
+++ b/src/common/hash.h
@@ -18,4 +18,11 @@ struct PairHash {
}
};
+template <typename T>
+struct IdentityHash {
+ [[nodiscard]] size_t operator()(T value) const noexcept {
+ return static_cast<size_t>(value);
+ }
+};
+
} // namespace Common
diff --git a/src/common/input.h b/src/common/input.h
index 825b0d650..cb30b7254 100644
--- a/src/common/input.h
+++ b/src/common/input.h
@@ -76,6 +76,19 @@ enum class PollingError {
Unknown,
};
+// Nfc reply from the controller
+enum class NfcState {
+ Success,
+ NewAmiibo,
+ WaitingForAmiibo,
+ AmiiboRemoved,
+ NotAnAmiibo,
+ NotSupported,
+ WrongDeviceState,
+ WriteFailed,
+ Unknown,
+};
+
// Ir camera reply from the controller
enum class CameraError {
None,
@@ -87,7 +100,6 @@ enum class CameraError {
enum class VibrationAmplificationType {
Linear,
Exponential,
- Test,
};
// Analog properties for calibration
@@ -202,6 +214,11 @@ struct CameraStatus {
std::vector<u8> data{};
};
+struct NfcStatus {
+ NfcState state{};
+ std::vector<u8> data{};
+};
+
// List of buttons to be passed to Qt that can be translated
enum class ButtonNames {
Undefined,
@@ -259,7 +276,9 @@ struct CallbackStatus {
BodyColorStatus color_status{};
BatteryStatus battery_status{};
VibrationStatus vibration_status{};
- CameraStatus camera_status{};
+ CameraFormat camera_status{CameraFormat::None};
+ NfcState nfc_status{NfcState::Unknown};
+ std::vector<u8> raw_data{};
};
// Triggered once every input change
@@ -305,6 +324,10 @@ public:
return VibrationError::NotSupported;
}
+ virtual bool IsVibrationEnabled() {
+ return false;
+ }
+
virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) {
return PollingError::NotSupported;
}
@@ -312,6 +335,14 @@ public:
virtual CameraError SetCameraFormat([[maybe_unused]] CameraFormat camera_format) {
return CameraError::NotSupported;
}
+
+ virtual NfcState SupportsNfc() const {
+ return NfcState::NotSupported;
+ }
+
+ virtual NfcState WriteNfcData([[maybe_unused]] const std::vector<u8>& data) {
+ return NfcState::NotSupported;
+ }
};
/// An abstract class template for a factory that can create input devices.
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 8ce1c2fd1..15d92505e 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -219,7 +219,7 @@ private:
void StartBackendThread() {
backend_thread = std::jthread([this](std::stop_token stop_token) {
- Common::SetCurrentThreadName("yuzu:Log");
+ Common::SetCurrentThreadName("Logger");
Entry entry;
const auto write_logs = [this, &entry]() {
ForEachBackend([&entry](Backend& backend) { backend.Write(entry); });
diff --git a/src/common/multi_level_page_table.cpp b/src/common/multi_level_page_table.cpp
new file mode 100644
index 000000000..46e362f3b
--- /dev/null
+++ b/src/common/multi_level_page_table.cpp
@@ -0,0 +1,9 @@
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/multi_level_page_table.inc"
+
+namespace Common {
+template class Common::MultiLevelPageTable<u64>;
+template class Common::MultiLevelPageTable<u32>;
+} // namespace Common
diff --git a/src/common/multi_level_page_table.h b/src/common/multi_level_page_table.h
new file mode 100644
index 000000000..31f6676a0
--- /dev/null
+++ b/src/common/multi_level_page_table.h
@@ -0,0 +1,78 @@
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "common/common_types.h"
+
+namespace Common {
+
+template <typename BaseAddr>
+class MultiLevelPageTable final {
+public:
+ constexpr MultiLevelPageTable() = default;
+ explicit MultiLevelPageTable(std::size_t address_space_bits, std::size_t first_level_bits,
+ std::size_t page_bits);
+
+ ~MultiLevelPageTable() noexcept;
+
+ MultiLevelPageTable(const MultiLevelPageTable&) = delete;
+ MultiLevelPageTable& operator=(const MultiLevelPageTable&) = delete;
+
+ MultiLevelPageTable(MultiLevelPageTable&& other) noexcept
+ : address_space_bits{std::exchange(other.address_space_bits, 0)},
+ first_level_bits{std::exchange(other.first_level_bits, 0)}, page_bits{std::exchange(
+ other.page_bits, 0)},
+ first_level_shift{std::exchange(other.first_level_shift, 0)},
+ first_level_chunk_size{std::exchange(other.first_level_chunk_size, 0)},
+ first_level_map{std::move(other.first_level_map)}, base_ptr{std::exchange(other.base_ptr,
+ nullptr)} {}
+
+ MultiLevelPageTable& operator=(MultiLevelPageTable&& other) noexcept {
+ address_space_bits = std::exchange(other.address_space_bits, 0);
+ first_level_bits = std::exchange(other.first_level_bits, 0);
+ page_bits = std::exchange(other.page_bits, 0);
+ first_level_shift = std::exchange(other.first_level_shift, 0);
+ first_level_chunk_size = std::exchange(other.first_level_chunk_size, 0);
+ alloc_size = std::exchange(other.alloc_size, 0);
+ first_level_map = std::move(other.first_level_map);
+ base_ptr = std::exchange(other.base_ptr, nullptr);
+ return *this;
+ }
+
+ void ReserveRange(u64 start, std::size_t size);
+
+ [[nodiscard]] const BaseAddr& operator[](std::size_t index) const {
+ return base_ptr[index];
+ }
+
+ [[nodiscard]] BaseAddr& operator[](std::size_t index) {
+ return base_ptr[index];
+ }
+
+ [[nodiscard]] BaseAddr* data() {
+ return base_ptr;
+ }
+
+ [[nodiscard]] const BaseAddr* data() const {
+ return base_ptr;
+ }
+
+private:
+ void AllocateLevel(u64 level);
+
+ std::size_t address_space_bits{};
+ std::size_t first_level_bits{};
+ std::size_t page_bits{};
+ std::size_t first_level_shift{};
+ std::size_t first_level_chunk_size{};
+ std::size_t alloc_size{};
+ std::vector<void*> first_level_map{};
+ BaseAddr* base_ptr{};
+};
+
+} // namespace Common
diff --git a/src/common/multi_level_page_table.inc b/src/common/multi_level_page_table.inc
new file mode 100644
index 000000000..8ac506fa0
--- /dev/null
+++ b/src/common/multi_level_page_table.inc
@@ -0,0 +1,84 @@
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/mman.h>
+#endif
+
+#include "common/assert.h"
+#include "common/multi_level_page_table.h"
+
+namespace Common {
+
+template <typename BaseAddr>
+MultiLevelPageTable<BaseAddr>::MultiLevelPageTable(std::size_t address_space_bits_,
+ std::size_t first_level_bits_,
+ std::size_t page_bits_)
+ : address_space_bits{address_space_bits_},
+ first_level_bits{first_level_bits_}, page_bits{page_bits_} {
+ if (page_bits == 0) {
+ return;
+ }
+ first_level_shift = address_space_bits - first_level_bits;
+ first_level_chunk_size = (1ULL << (first_level_shift - page_bits)) * sizeof(BaseAddr);
+ alloc_size = (1ULL << (address_space_bits - page_bits)) * sizeof(BaseAddr);
+ std::size_t first_level_size = 1ULL << first_level_bits;
+ first_level_map.resize(first_level_size, nullptr);
+#ifdef _WIN32
+ void* base{VirtualAlloc(nullptr, alloc_size, MEM_RESERVE, PAGE_READWRITE)};
+#else
+ void* base{mmap(nullptr, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)};
+
+ if (base == MAP_FAILED) {
+ base = nullptr;
+ }
+#endif
+
+ ASSERT(base);
+ base_ptr = reinterpret_cast<BaseAddr*>(base);
+}
+
+template <typename BaseAddr>
+MultiLevelPageTable<BaseAddr>::~MultiLevelPageTable() noexcept {
+ if (!base_ptr) {
+ return;
+ }
+#ifdef _WIN32
+ ASSERT(VirtualFree(base_ptr, 0, MEM_RELEASE));
+#else
+ ASSERT(munmap(base_ptr, alloc_size) == 0);
+#endif
+}
+
+template <typename BaseAddr>
+void MultiLevelPageTable<BaseAddr>::ReserveRange(u64 start, std::size_t size) {
+ const u64 new_start = start >> first_level_shift;
+ const u64 new_end = (start + size) >> first_level_shift;
+ for (u64 i = new_start; i <= new_end; i++) {
+ if (!first_level_map[i]) {
+ AllocateLevel(i);
+ }
+ }
+}
+
+template <typename BaseAddr>
+void MultiLevelPageTable<BaseAddr>::AllocateLevel(u64 level) {
+ void* ptr = reinterpret_cast<char *>(base_ptr) + level * first_level_chunk_size;
+#ifdef _WIN32
+ void* base{VirtualAlloc(ptr, first_level_chunk_size, MEM_COMMIT, PAGE_READWRITE)};
+#else
+ void* base{mmap(ptr, first_level_chunk_size, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)};
+
+ if (base == MAP_FAILED) {
+ base = nullptr;
+ }
+#endif
+ ASSERT(base);
+
+ first_level_map[level] = base;
+}
+
+} // namespace Common
diff --git a/src/common/settings.h b/src/common/settings.h
index 851812f28..0eb98939c 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -431,7 +431,7 @@ struct Values {
FullscreenMode::Exclusive,
#endif
FullscreenMode::Borderless, FullscreenMode::Exclusive, "fullscreen_mode"};
- SwitchableSetting<int, true> aspect_ratio{0, 0, 3, "aspect_ratio"};
+ SwitchableSetting<int, true> aspect_ratio{0, 0, 4, "aspect_ratio"};
SwitchableSetting<int, true> max_anisotropy{0, 0, 5, "max_anisotropy"};
SwitchableSetting<bool> use_speed_limit{true, "use_speed_limit"};
SwitchableSetting<u16, true> speed_limit{100, 0, 9999, "speed_limit"};
@@ -531,6 +531,7 @@ struct Values {
Setting<bool> use_auto_stub{false, "use_auto_stub"};
Setting<bool> enable_all_controllers{false, "enable_all_controllers"};
Setting<bool> create_crash_dumps{false, "create_crash_dumps"};
+ Setting<bool> perform_vulkan_check{true, "perform_vulkan_check"};
// Miscellaneous
Setting<std::string> log_filter{"*:Info", "log_filter"};
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 33cf470d5..113e663b5 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -138,8 +138,6 @@ add_library(core STATIC
frontend/emu_window.h
frontend/framebuffer_layout.cpp
frontend/framebuffer_layout.h
- hardware_interrupt_manager.cpp
- hardware_interrupt_manager.h
hid/emulated_console.cpp
hid/emulated_console.h
hid/emulated_controller.cpp
@@ -192,6 +190,9 @@ add_library(core STATIC
hle/kernel/k_code_memory.h
hle/kernel/k_condition_variable.cpp
hle/kernel/k_condition_variable.h
+ hle/kernel/k_dynamic_page_manager.h
+ hle/kernel/k_dynamic_resource_manager.h
+ hle/kernel/k_dynamic_slab_heap.h
hle/kernel/k_event.cpp
hle/kernel/k_event.h
hle/kernel/k_handle_table.cpp
@@ -242,6 +243,8 @@ add_library(core STATIC
hle/kernel/k_server_session.h
hle/kernel/k_session.cpp
hle/kernel/k_session.h
+ hle/kernel/k_session_request.cpp
+ hle/kernel/k_session_request.h
hle/kernel/k_shared_memory.cpp
hle/kernel/k_shared_memory.h
hle/kernel/k_shared_memory_info.h
@@ -263,8 +266,6 @@ add_library(core STATIC
hle/kernel/k_worker_task.h
hle/kernel/k_worker_task_manager.cpp
hle/kernel/k_worker_task_manager.h
- hle/kernel/k_writable_event.cpp
- hle/kernel/k_writable_event.h
hle/kernel/kernel.cpp
hle/kernel/kernel.h
hle/kernel/memory_types.h
@@ -460,6 +461,8 @@ add_library(core STATIC
hle/service/hid/controllers/mouse.h
hle/service/hid/controllers/npad.cpp
hle/service/hid/controllers/npad.h
+ hle/service/hid/controllers/palma.cpp
+ hle/service/hid/controllers/palma.h
hle/service/hid/controllers/stubbed.cpp
hle/service/hid/controllers/stubbed.h
hle/service/hid/controllers/touchscreen.cpp
@@ -494,6 +497,8 @@ add_library(core STATIC
hle/service/jit/jit.h
hle/service/lbl/lbl.cpp
hle/service/lbl/lbl.h
+ hle/service/ldn/lan_discovery.cpp
+ hle/service/ldn/lan_discovery.h
hle/service/ldn/ldn_results.h
hle/service/ldn/ldn.cpp
hle/service/ldn/ldn.h
@@ -521,9 +526,12 @@ add_library(core STATIC
hle/service/nfc/nfc.h
hle/service/nfp/amiibo_crypto.cpp
hle/service/nfp/amiibo_crypto.h
- hle/service/nfp/amiibo_types.h
hle/service/nfp/nfp.cpp
hle/service/nfp/nfp.h
+ hle/service/nfp/nfp_device.cpp
+ hle/service/nfp/nfp_device.h
+ hle/service/nfp/nfp_result.h
+ hle/service/nfp/nfp_types.h
hle/service/nfp/nfp_user.cpp
hle/service/nfp/nfp_user.h
hle/service/ngct/ngct.cpp
@@ -543,6 +551,12 @@ add_library(core STATIC
hle/service/ns/ns.h
hle/service/ns/pdm_qry.cpp
hle/service/ns/pdm_qry.h
+ hle/service/nvdrv/core/container.cpp
+ hle/service/nvdrv/core/container.h
+ hle/service/nvdrv/core/nvmap.cpp
+ hle/service/nvdrv/core/nvmap.h
+ hle/service/nvdrv/core/syncpoint_manager.cpp
+ hle/service/nvdrv/core/syncpoint_manager.h
hle/service/nvdrv/devices/nvdevice.h
hle/service/nvdrv/devices/nvdisp_disp0.cpp
hle/service/nvdrv/devices/nvdisp_disp0.h
@@ -571,8 +585,6 @@ add_library(core STATIC
hle/service/nvdrv/nvdrv_interface.h
hle/service/nvdrv/nvmemp.cpp
hle/service/nvdrv/nvmemp.h
- hle/service/nvdrv/syncpoint_manager.cpp
- hle/service/nvdrv/syncpoint_manager.h
hle/service/nvflinger/binder.h
hle/service/nvflinger/buffer_item.h
hle/service/nvflinger/buffer_item_consumer.cpp
@@ -762,19 +774,15 @@ if (MSVC)
/we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data
/we4245 # 'conversion': conversion from 'type1' to 'type2', signed/unsigned mismatch
/we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
+ /we4800 # Implicit conversion from 'type' to bool. Possible information loss
)
else()
target_compile_options(core PRIVATE
-Werror=conversion
- -Werror=ignored-qualifiers
- $<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess>
- $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter>
- $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable>
+ -Wno-sign-conversion
$<$<CXX_COMPILER_ID:Clang>:-fsized-deallocation>
-
- -Wno-sign-conversion
)
endif()
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 953d96439..29ba562dc 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -134,6 +134,14 @@ void ARM_Interface::Run() {
}
system.ExitDynarmicProfile();
+ // If the thread is scheduled for termination, exit the thread.
+ if (current_thread->HasDpc()) {
+ if (current_thread->IsTerminationRequested()) {
+ current_thread->Exit();
+ UNREACHABLE();
+ }
+ }
+
// Notify the debugger and go to sleep if a breakpoint was hit,
// or if the thread is unable to continue for any reason.
if (Has(hr, breakpoint) || Has(hr, no_execute)) {
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index d1e70f19d..287ba102e 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -450,7 +450,7 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_32::GetBacktrace(Core::S
// Frame records are two words long:
// fp+0 : pointer to previous frame record
// fp+4 : value of lr for frame
- while (true) {
+ for (size_t i = 0; i < 256; i++) {
out.push_back({"", 0, lr, 0, ""});
if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 8)) {
break;
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 1d46f6d40..afb7fb3a0 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -111,6 +111,7 @@ public:
LOG_ERROR(Core_ARM,
"Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc,
num_instructions, memory.Read32(pc));
+ ReturnException(pc, ARM_Interface::no_execute);
}
void InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op,
@@ -516,7 +517,7 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Dynarmic_64::GetBacktrace(Core::S
// Frame records are two words long:
// fp+0 : pointer to previous frame record
// fp+8 : value of lr for frame
- while (true) {
+ for (size_t i = 0; i < 256; i++) {
out.push_back({"", 0, lr, 0, ""});
if (!fp || (fp % 4 != 0) || !memory.IsValidVirtualAddressRange(fp, 16)) {
break;
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 121092868..d8934be52 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -27,7 +27,6 @@
#include "core/file_sys/savedata_factory.h"
#include "core/file_sys/vfs_concat.h"
#include "core/file_sys/vfs_real.h"
-#include "core/hardware_interrupt_manager.h"
#include "core/hid/hid_core.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/kernel/k_process.h"
@@ -51,6 +50,7 @@
#include "core/telemetry_session.h"
#include "core/tools/freezer.h"
#include "network/network.h"
+#include "video_core/host1x/host1x.h"
#include "video_core/renderer_base.h"
#include "video_core/video_core.h"
@@ -133,6 +133,56 @@ struct System::Impl {
: kernel{system}, fs_controller{system}, memory{system}, hid_core{}, room_network{},
cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {}
+ void Initialize(System& system) {
+ device_memory = std::make_unique<Core::DeviceMemory>();
+
+ is_multicore = Settings::values.use_multi_core.GetValue();
+ extended_memory_layout = Settings::values.use_extended_memory_layout.GetValue();
+
+ core_timing.SetMulticore(is_multicore);
+ core_timing.Initialize([&system]() { system.RegisterHostThread(); });
+
+ const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
+ const auto current_time =
+ std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
+ Settings::values.custom_rtc_differential =
+ Settings::values.custom_rtc.value_or(current_time) - current_time;
+
+ // Create a default fs if one doesn't already exist.
+ if (virtual_filesystem == nullptr) {
+ virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
+ }
+ if (content_provider == nullptr) {
+ content_provider = std::make_unique<FileSys::ContentProviderUnion>();
+ }
+
+ // Create default implementations of applets if one is not provided.
+ applet_manager.SetDefaultAppletsIfMissing();
+
+ is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
+
+ kernel.SetMulticore(is_multicore);
+ cpu_manager.SetMulticore(is_multicore);
+ cpu_manager.SetAsyncGpu(is_async_gpu);
+ }
+
+ void ReinitializeIfNecessary(System& system) {
+ const bool must_reinitialize =
+ is_multicore != Settings::values.use_multi_core.GetValue() ||
+ extended_memory_layout != Settings::values.use_extended_memory_layout.GetValue();
+
+ if (!must_reinitialize) {
+ return;
+ }
+
+ LOG_DEBUG(Kernel, "Re-initializing");
+
+ is_multicore = Settings::values.use_multi_core.GetValue();
+ extended_memory_layout = Settings::values.use_extended_memory_layout.GetValue();
+
+ Initialize(system);
+ }
+
SystemResultStatus Run() {
std::unique_lock<std::mutex> lk(suspend_guard);
status = SystemResultStatus::Success;
@@ -178,43 +228,21 @@ struct System::Impl {
debugger = std::make_unique<Debugger>(system, port);
}
- SystemResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
+ SystemResultStatus SetupForMainProcess(System& system, Frontend::EmuWindow& emu_window) {
LOG_DEBUG(Core, "initialized OK");
- device_memory = std::make_unique<Core::DeviceMemory>();
-
- is_multicore = Settings::values.use_multi_core.GetValue();
- is_async_gpu = Settings::values.use_asynchronous_gpu_emulation.GetValue();
-
- kernel.SetMulticore(is_multicore);
- cpu_manager.SetMulticore(is_multicore);
- cpu_manager.SetAsyncGpu(is_async_gpu);
- core_timing.SetMulticore(is_multicore);
+ // Setting changes may require a full system reinitialization (e.g., disabling multicore).
+ ReinitializeIfNecessary(system);
kernel.Initialize();
cpu_manager.Initialize();
- core_timing.Initialize([&system]() { system.RegisterHostThread(); });
-
- const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
- const auto current_time =
- std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
- Settings::values.custom_rtc_differential =
- Settings::values.custom_rtc.value_or(current_time) - current_time;
-
- // Create a default fs if one doesn't already exist.
- if (virtual_filesystem == nullptr)
- virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
- if (content_provider == nullptr)
- content_provider = std::make_unique<FileSys::ContentProviderUnion>();
-
- /// Create default implementations of applets if one is not provided.
- applet_manager.SetDefaultAppletsIfMissing();
/// Reset all glue registrations
arp_manager.ResetAll();
telemetry_session = std::make_unique<Core::TelemetrySession>();
+ host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system);
gpu_core = VideoCore::CreateGPU(emu_window, system);
if (!gpu_core) {
return SystemResultStatus::ErrorVideoCore;
@@ -224,7 +252,6 @@ struct System::Impl {
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
services = std::make_unique<Service::Services>(service_manager, system);
- interrupt_manager = std::make_unique<Hardware::InterruptManager>(system);
// Initialize time manager, which must happen after kernel is created
time_manager.Initialize();
@@ -253,11 +280,11 @@ struct System::Impl {
return SystemResultStatus::ErrorGetLoader;
}
- SystemResultStatus init_result{Init(system, emu_window)};
+ SystemResultStatus init_result{SetupForMainProcess(system, emu_window)};
if (init_result != SystemResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
static_cast<int>(init_result));
- Shutdown();
+ ShutdownMainProcess();
return init_result;
}
@@ -276,7 +303,7 @@ struct System::Impl {
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
if (load_result != Loader::ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
- Shutdown();
+ ShutdownMainProcess();
return static_cast<SystemResultStatus>(
static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
@@ -335,7 +362,7 @@ struct System::Impl {
return status;
}
- void Shutdown() {
+ void ShutdownMainProcess() {
SetShuttingDown(true);
// Log last frame performance stats if game was loded
@@ -363,20 +390,21 @@ struct System::Impl {
kernel.ShutdownCores();
cpu_manager.Shutdown();
debugger.reset();
+ services->KillNVNFlinger();
kernel.CloseServices();
services.reset();
service_manager.reset();
cheat_engine.reset();
telemetry_session.reset();
time_manager.Shutdown();
- core_timing.Shutdown();
+ core_timing.ClearPendingEvents();
app_loader.reset();
audio_core.reset();
gpu_core.reset();
+ host1x_core.reset();
perf_stats.reset();
kernel.Shutdown();
memory.Reset();
- applet_manager.ClearAll();
if (auto room_member = room_network.GetRoomMember().lock()) {
Network::GameInfo game_info{};
@@ -450,7 +478,7 @@ struct System::Impl {
/// AppLoader used to load the current executing application
std::unique_ptr<Loader::AppLoader> app_loader;
std::unique_ptr<Tegra::GPU> gpu_core;
- std::unique_ptr<Hardware::InterruptManager> interrupt_manager;
+ std::unique_ptr<Tegra::Host1x::Host1x> host1x_core;
std::unique_ptr<Core::DeviceMemory> device_memory;
std::unique_ptr<AudioCore::AudioCore> audio_core;
Core::Memory::Memory memory;
@@ -499,6 +527,7 @@ struct System::Impl {
bool is_multicore{};
bool is_async_gpu{};
+ bool extended_memory_layout{};
ExecuteProgramCallback execute_program_callback;
ExitCallback exit_callback;
@@ -519,6 +548,10 @@ const CpuManager& System::GetCpuManager() const {
return impl->cpu_manager;
}
+void System::Initialize() {
+ impl->Initialize(*this);
+}
+
SystemResultStatus System::Run() {
return impl->Run();
}
@@ -539,8 +572,8 @@ void System::InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size) {
impl->kernel.InvalidateCpuInstructionCacheRange(addr, size);
}
-void System::Shutdown() {
- impl->Shutdown();
+void System::ShutdownMainProcess() {
+ impl->ShutdownMainProcess();
}
bool System::IsShuttingDown() const {
@@ -668,12 +701,12 @@ const Tegra::GPU& System::GPU() const {
return *impl->gpu_core;
}
-Core::Hardware::InterruptManager& System::InterruptManager() {
- return *impl->interrupt_manager;
+Tegra::Host1x::Host1x& System::Host1x() {
+ return *impl->host1x_core;
}
-const Core::Hardware::InterruptManager& System::InterruptManager() const {
- return *impl->interrupt_manager;
+const Tegra::Host1x::Host1x& System::Host1x() const {
+ return *impl->host1x_core;
}
VideoCore::RendererBase& System::Renderer() {
diff --git a/src/core/core.h b/src/core/core.h
index 0ce3b1d60..4ebedffd9 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -74,6 +74,9 @@ class TimeManager;
namespace Tegra {
class DebugContext;
class GPU;
+namespace Host1x {
+class Host1x;
+} // namespace Host1x
} // namespace Tegra
namespace VideoCore {
@@ -88,10 +91,6 @@ namespace Core::Timing {
class CoreTiming;
}
-namespace Core::Hardware {
-class InterruptManager;
-}
-
namespace Core::HID {
class HIDCore;
}
@@ -144,6 +143,12 @@ public:
System& operator=(System&&) = delete;
/**
+ * Initializes the system
+ * This function will initialize core functionaility used for system emulation
+ */
+ void Initialize();
+
+ /**
* Run the OS and Application
* This function will start emulation and run the relevant devices
*/
@@ -167,8 +172,8 @@ public:
void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
- /// Shutdown the emulated system.
- void Shutdown();
+ /// Shutdown the main emulated process.
+ void ShutdownMainProcess();
/// Check if the core is shutting down.
[[nodiscard]] bool IsShuttingDown() const;
@@ -260,6 +265,12 @@ public:
/// Gets an immutable reference to the GPU interface.
[[nodiscard]] const Tegra::GPU& GPU() const;
+ /// Gets a mutable reference to the Host1x interface
+ [[nodiscard]] Tegra::Host1x::Host1x& Host1x();
+
+ /// Gets an immutable reference to the Host1x interface.
+ [[nodiscard]] const Tegra::Host1x::Host1x& Host1x() const;
+
/// Gets a mutable reference to the renderer.
[[nodiscard]] VideoCore::RendererBase& Renderer();
@@ -296,12 +307,6 @@ public:
/// Provides a constant reference to the core timing instance.
[[nodiscard]] const Timing::CoreTiming& CoreTiming() const;
- /// Provides a reference to the interrupt manager instance.
- [[nodiscard]] Core::Hardware::InterruptManager& InterruptManager();
-
- /// Provides a constant reference to the interrupt manager instance.
- [[nodiscard]] const Core::Hardware::InterruptManager& InterruptManager() const;
-
/// Provides a reference to the kernel instance.
[[nodiscard]] Kernel::KernelCore& Kernel();
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index f6c4567ba..0e7b5f943 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -40,10 +40,12 @@ struct CoreTiming::Event {
CoreTiming::CoreTiming()
: clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {}
-CoreTiming::~CoreTiming() = default;
+CoreTiming::~CoreTiming() {
+ Reset();
+}
void CoreTiming::ThreadEntry(CoreTiming& instance) {
- constexpr char name[] = "yuzu:HostTiming";
+ constexpr char name[] = "HostTiming";
MicroProfileOnThreadCreate(name);
Common::SetCurrentThreadName(name);
Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);
@@ -53,6 +55,7 @@ void CoreTiming::ThreadEntry(CoreTiming& instance) {
}
void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
+ Reset();
on_thread_init = std::move(on_thread_init_);
event_fifo_id = 0;
shutting_down = false;
@@ -65,17 +68,8 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
}
}
-void CoreTiming::Shutdown() {
- paused = true;
- shutting_down = true;
- pause_event.Set();
- event.Set();
- if (timer_thread) {
- timer_thread->join();
- }
- ClearPendingEvents();
- timer_thread.reset();
- has_started = false;
+void CoreTiming::ClearPendingEvents() {
+ event_queue.clear();
}
void CoreTiming::Pause(bool is_paused) {
@@ -196,10 +190,6 @@ u64 CoreTiming::GetClockTicks() const {
return CpuCyclesToClockCycles(ticks);
}
-void CoreTiming::ClearPendingEvents() {
- event_queue.clear();
-}
-
void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) {
std::scoped_lock lock{basic_lock};
@@ -270,6 +260,7 @@ void CoreTiming::ThreadLoop() {
// There are more events left in the queue, wait until the next event.
const auto wait_time = *next_time - GetGlobalTimeNs().count();
if (wait_time > 0) {
+#ifdef _WIN32
// Assume a timer resolution of 1ms.
static constexpr s64 TimerResolutionNS = 1000000;
@@ -287,6 +278,9 @@ void CoreTiming::ThreadLoop() {
if (event.IsSet()) {
event.Reset();
}
+#else
+ event.WaitFor(std::chrono::nanoseconds(wait_time));
+#endif
}
} else {
// Queue is empty, wait until another event is scheduled and signals us to continue.
@@ -303,6 +297,18 @@ void CoreTiming::ThreadLoop() {
}
}
+void CoreTiming::Reset() {
+ paused = true;
+ shutting_down = true;
+ pause_event.Set();
+ event.Set();
+ if (timer_thread) {
+ timer_thread->join();
+ }
+ timer_thread.reset();
+ has_started = false;
+}
+
std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const {
if (is_multicore) {
return clock->GetTimeNS();
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index 3259397b2..b5925193c 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -61,19 +61,14 @@ public:
/// required to end slice - 1 and start slice 0 before the first cycle of code is executed.
void Initialize(std::function<void()>&& on_thread_init_);
- /// Tears down all timing related functionality.
- void Shutdown();
+ /// Clear all pending events. This should ONLY be done on exit.
+ void ClearPendingEvents();
/// Sets if emulation is multicore or single core, must be set before Initialize
void SetMulticore(bool is_multicore_) {
is_multicore = is_multicore_;
}
- /// Check if it's using host timing.
- bool IsHostTiming() const {
- return is_multicore;
- }
-
/// Pauses/Unpauses the execution of the timer thread.
void Pause(bool is_paused);
@@ -136,12 +131,11 @@ public:
private:
struct Event;
- /// Clear all pending events. This should ONLY be done on exit.
- void ClearPendingEvents();
-
static void ThreadEntry(CoreTiming& instance);
void ThreadLoop();
+ void Reset();
+
std::unique_ptr<Common::WallClock> clock;
s64 global_timer = 0;
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index 9b1565ae1..0dd4c2196 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -189,9 +189,9 @@ void CpuManager::RunThread(std::size_t core) {
system.RegisterCoreThread(core);
std::string name;
if (is_multicore) {
- name = "yuzu:CPUCore_" + std::to_string(core);
+ name = "CPUCore_" + std::to_string(core);
} else {
- name = "yuzu:CPUThread";
+ name = "CPUThread";
}
MicroProfileOnThreadCreate(name.c_str());
Common::SetCurrentThreadName(name.c_str());
diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp
index e42bdd17d..339f971e6 100644
--- a/src/core/debugger/debugger.cpp
+++ b/src/core/debugger/debugger.cpp
@@ -140,7 +140,7 @@ private:
}
void ThreadLoop(std::stop_token stop_token) {
- Common::SetCurrentThreadName("yuzu:Debugger");
+ Common::SetCurrentThreadName("Debugger");
// Set up the client signals for new data.
AsyncReceiveInto(signal_pipe, pipe_data, [&](auto d) { PipeData(d); });
diff --git a/src/core/device_memory.h b/src/core/device_memory.h
index df61b0c0b..90510733c 100644
--- a/src/core/device_memory.h
+++ b/src/core/device_memory.h
@@ -31,12 +31,14 @@ public:
DramMemoryMap::Base;
}
- u8* GetPointer(PAddr addr) {
- return buffer.BackingBasePointer() + (addr - DramMemoryMap::Base);
+ template <typename T>
+ T* GetPointer(PAddr addr) {
+ return reinterpret_cast<T*>(buffer.BackingBasePointer() + (addr - DramMemoryMap::Base));
}
- const u8* GetPointer(PAddr addr) const {
- return buffer.BackingBasePointer() + (addr - DramMemoryMap::Base);
+ template <typename T>
+ const T* GetPointer(PAddr addr) const {
+ return reinterpret_cast<T*>(buffer.BackingBasePointer() + (addr - DramMemoryMap::Base));
}
Common::HostMemory buffer;
diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp
index f23d9373b..5d02865f4 100644
--- a/src/core/file_sys/card_image.cpp
+++ b/src/core/file_sys/card_image.cpp
@@ -232,8 +232,8 @@ const std::vector<std::shared_ptr<NCA>>& XCI::GetNCAs() const {
std::shared_ptr<NCA> XCI::GetNCAByType(NCAContentType type) const {
const auto program_id = secure_partition->GetProgramTitleID();
- const auto iter = std::find_if(
- ncas.begin(), ncas.end(), [this, type, program_id](const std::shared_ptr<NCA>& nca) {
+ const auto iter =
+ std::find_if(ncas.begin(), ncas.end(), [type, program_id](const std::shared_ptr<NCA>& nca) {
return nca->GetType() == type && nca->GetTitleId() == program_id;
});
return iter == ncas.end() ? nullptr : *iter;
diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp
index be25da2f6..50f44f598 100644
--- a/src/core/file_sys/control_metadata.cpp
+++ b/src/core/file_sys/control_metadata.cpp
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include "common/settings.h"
#include "common/string_util.h"
#include "common/swap.h"
#include "core/file_sys/control_metadata.h"
@@ -37,6 +38,27 @@ std::string LanguageEntry::GetDeveloperName() const {
developer_name.size());
}
+constexpr std::array<Language, 18> language_to_codes = {{
+ Language::Japanese,
+ Language::AmericanEnglish,
+ Language::French,
+ Language::German,
+ Language::Italian,
+ Language::Spanish,
+ Language::Chinese,
+ Language::Korean,
+ Language::Dutch,
+ Language::Portuguese,
+ Language::Russian,
+ Language::Taiwanese,
+ Language::BritishEnglish,
+ Language::CanadianFrench,
+ Language::LatinAmericanSpanish,
+ Language::Chinese,
+ Language::Taiwanese,
+ Language::BrazilianPortuguese,
+}};
+
NACP::NACP() = default;
NACP::NACP(VirtualFile file) {
@@ -45,9 +67,13 @@ NACP::NACP(VirtualFile file) {
NACP::~NACP() = default;
-const LanguageEntry& NACP::GetLanguageEntry(Language language) const {
- if (language != Language::Default) {
- return raw.language_entries.at(static_cast<u8>(language));
+const LanguageEntry& NACP::GetLanguageEntry() const {
+ Language language = language_to_codes[Settings::values.language_index.GetValue()];
+
+ {
+ const auto& language_entry = raw.language_entries.at(static_cast<u8>(language));
+ if (!language_entry.GetApplicationName().empty())
+ return language_entry;
}
for (const auto& language_entry : raw.language_entries) {
@@ -55,16 +81,15 @@ const LanguageEntry& NACP::GetLanguageEntry(Language language) const {
return language_entry;
}
- // Fallback to English
- return GetLanguageEntry(Language::AmericanEnglish);
+ return raw.language_entries.at(static_cast<u8>(Language::AmericanEnglish));
}
-std::string NACP::GetApplicationName(Language language) const {
- return GetLanguageEntry(language).GetApplicationName();
+std::string NACP::GetApplicationName() const {
+ return GetLanguageEntry().GetApplicationName();
}
-std::string NACP::GetDeveloperName(Language language) const {
- return GetLanguageEntry(language).GetDeveloperName();
+std::string NACP::GetDeveloperName() const {
+ return GetLanguageEntry().GetDeveloperName();
}
u64 NACP::GetTitleId() const {
diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h
index 75295519c..6a81873b1 100644
--- a/src/core/file_sys/control_metadata.h
+++ b/src/core/file_sys/control_metadata.h
@@ -101,9 +101,9 @@ public:
explicit NACP(VirtualFile file);
~NACP();
- const LanguageEntry& GetLanguageEntry(Language language = Language::Default) const;
- std::string GetApplicationName(Language language = Language::Default) const;
- std::string GetDeveloperName(Language language = Language::Default) const;
+ const LanguageEntry& GetLanguageEntry() const;
+ std::string GetApplicationName() const;
+ std::string GetDeveloperName() const;
u64 GetTitleId() const;
u64 GetDLCBaseTitleId() const;
std::string GetVersionString() const;
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp
index e0cdf3520..f00479bd3 100644
--- a/src/core/file_sys/program_metadata.cpp
+++ b/src/core/file_sys/program_metadata.cpp
@@ -33,11 +33,55 @@ Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) {
return Loader::ResultStatus::ErrorBadACIHeader;
}
- if (sizeof(FileAccessControl) != file->ReadObject(&acid_file_access, acid_header.fac_offset)) {
+ // Load acid_file_access per-component instead of the entire struct, since this struct does not
+ // reflect the layout of the real data.
+ std::size_t current_offset = acid_header.fac_offset;
+ if (sizeof(FileAccessControl::version) != file->ReadBytes(&acid_file_access.version,
+ sizeof(FileAccessControl::version),
+ current_offset)) {
+ return Loader::ResultStatus::ErrorBadFileAccessControl;
+ }
+ if (sizeof(FileAccessControl::permissions) !=
+ file->ReadBytes(&acid_file_access.permissions, sizeof(FileAccessControl::permissions),
+ current_offset += sizeof(FileAccessControl::version) + 3)) {
+ return Loader::ResultStatus::ErrorBadFileAccessControl;
+ }
+ if (sizeof(FileAccessControl::unknown) !=
+ file->ReadBytes(&acid_file_access.unknown, sizeof(FileAccessControl::unknown),
+ current_offset + sizeof(FileAccessControl::permissions))) {
return Loader::ResultStatus::ErrorBadFileAccessControl;
}
- if (sizeof(FileAccessHeader) != file->ReadObject(&aci_file_access, aci_header.fah_offset)) {
+ // Load aci_file_access per-component instead of the entire struct, same as acid_file_access
+ current_offset = aci_header.fah_offset;
+ if (sizeof(FileAccessHeader::version) != file->ReadBytes(&aci_file_access.version,
+ sizeof(FileAccessHeader::version),
+ current_offset)) {
+ return Loader::ResultStatus::ErrorBadFileAccessHeader;
+ }
+ if (sizeof(FileAccessHeader::permissions) !=
+ file->ReadBytes(&aci_file_access.permissions, sizeof(FileAccessHeader::permissions),
+ current_offset += sizeof(FileAccessHeader::version) + 3)) {
+ return Loader::ResultStatus::ErrorBadFileAccessHeader;
+ }
+ if (sizeof(FileAccessHeader::unk_offset) !=
+ file->ReadBytes(&aci_file_access.unk_offset, sizeof(FileAccessHeader::unk_offset),
+ current_offset += sizeof(FileAccessHeader::permissions))) {
+ return Loader::ResultStatus::ErrorBadFileAccessHeader;
+ }
+ if (sizeof(FileAccessHeader::unk_size) !=
+ file->ReadBytes(&aci_file_access.unk_size, sizeof(FileAccessHeader::unk_size),
+ current_offset += sizeof(FileAccessHeader::unk_offset))) {
+ return Loader::ResultStatus::ErrorBadFileAccessHeader;
+ }
+ if (sizeof(FileAccessHeader::unk_offset_2) !=
+ file->ReadBytes(&aci_file_access.unk_offset_2, sizeof(FileAccessHeader::unk_offset_2),
+ current_offset += sizeof(FileAccessHeader::unk_size))) {
+ return Loader::ResultStatus::ErrorBadFileAccessHeader;
+ }
+ if (sizeof(FileAccessHeader::unk_size_2) !=
+ file->ReadBytes(&aci_file_access.unk_size_2, sizeof(FileAccessHeader::unk_size_2),
+ current_offset + sizeof(FileAccessHeader::unk_offset_2))) {
return Loader::ResultStatus::ErrorBadFileAccessHeader;
}
@@ -83,7 +127,7 @@ void ProgramMetadata::LoadManual(bool is_64_bit, ProgramAddressSpaceType address
}
bool ProgramMetadata::Is64BitProgram() const {
- return npdm_header.has_64_bit_instructions;
+ return npdm_header.has_64_bit_instructions.As<bool>();
}
ProgramAddressSpaceType ProgramMetadata::GetAddressSpaceType() const {
@@ -152,9 +196,7 @@ void ProgramMetadata::Print() const {
LOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO");
LOG_DEBUG(Service_FS, "Title ID Min: 0x{:016X}", acid_header.title_id_min);
LOG_DEBUG(Service_FS, "Title ID Max: 0x{:016X}", acid_header.title_id_max);
- u64_le permissions_l; // local copy to fix alignment error
- std::memcpy(&permissions_l, &acid_file_access.permissions, sizeof(permissions_l));
- LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", permissions_l);
+ LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", acid_file_access.permissions);
// Begin ACI0 printing (actual perms, unsigned)
LOG_DEBUG(Service_FS, "Magic: {:.4}", aci_header.magic.data());
diff --git a/src/core/file_sys/program_metadata.h b/src/core/file_sys/program_metadata.h
index e8fb4e27f..2e8960b07 100644
--- a/src/core/file_sys/program_metadata.h
+++ b/src/core/file_sys/program_metadata.h
@@ -144,20 +144,18 @@ private:
static_assert(sizeof(AciHeader) == 0x40, "ACI0 header structure size is wrong");
-#pragma pack(push, 1)
-
+ // FileAccessControl and FileAccessHeader need loaded per-component: this layout does not
+ // reflect the real layout to avoid reference binding to misaligned addresses
struct FileAccessControl {
u8 version;
- INSERT_PADDING_BYTES(3);
+ // 3 padding bytes
u64_le permissions;
std::array<u8, 0x20> unknown;
};
- static_assert(sizeof(FileAccessControl) == 0x2C, "FS access control structure size is wrong");
-
struct FileAccessHeader {
u8 version;
- INSERT_PADDING_BYTES(3);
+ // 3 padding bytes
u64_le permissions;
u32_le unk_offset;
u32_le unk_size;
@@ -165,10 +163,6 @@ private:
u32_le unk_size_2;
};
- static_assert(sizeof(FileAccessHeader) == 0x1C, "FS access header structure size is wrong");
-
-#pragma pack(pop)
-
Header npdm_header;
AciHeader aci_header;
AcidHeader acid_header;
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp
index 8c1b2523c..1567da231 100644
--- a/src/core/file_sys/savedata_factory.cpp
+++ b/src/core/file_sys/savedata_factory.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "common/logging/log.h"
+#include "common/uuid.h"
#include "core/core.h"
#include "core/file_sys/savedata_factory.h"
#include "core/file_sys/vfs.h"
@@ -59,6 +60,36 @@ bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataA
attr.title_id == 0 && attr.save_id == 0);
}
+std::string GetFutureSaveDataPath(SaveDataSpaceId space_id, SaveDataType type, u64 title_id,
+ u128 user_id) {
+ // Only detect nand user saves.
+ const auto space_id_path = [space_id]() -> std::string_view {
+ switch (space_id) {
+ case SaveDataSpaceId::NandUser:
+ return "/user/save";
+ default:
+ return "";
+ }
+ }();
+
+ if (space_id_path.empty()) {
+ return "";
+ }
+
+ Common::UUID uuid;
+ std::memcpy(uuid.uuid.data(), user_id.data(), sizeof(Common::UUID));
+
+ // Only detect account/device saves from the future location.
+ switch (type) {
+ case SaveDataType::SaveData:
+ return fmt::format("{}/account/{}/{:016X}/1", space_id_path, uuid.RawString(), title_id);
+ case SaveDataType::DeviceSaveData:
+ return fmt::format("{}/device/{:016X}/1", space_id_path, title_id);
+ default:
+ return "";
+ }
+}
+
} // Anonymous namespace
std::string SaveDataAttribute::DebugInfo() const {
@@ -82,7 +113,7 @@ ResultVal<VirtualDir> SaveDataFactory::Create(SaveDataSpaceId space,
PrintSaveDataAttributeWarnings(meta);
const auto save_directory =
- GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
+ GetFullPath(system, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
auto out = dir->CreateDirectoryRelative(save_directory);
@@ -99,7 +130,7 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space,
const SaveDataAttribute& meta) const {
const auto save_directory =
- GetFullPath(system, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
+ GetFullPath(system, dir, space, meta.type, meta.title_id, meta.user_id, meta.save_id);
auto out = dir->GetDirectoryRelative(save_directory);
@@ -134,9 +165,9 @@ std::string SaveDataFactory::GetSaveDataSpaceIdPath(SaveDataSpaceId space) {
}
}
-std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId space,
- SaveDataType type, u64 title_id, u128 user_id,
- u64 save_id) {
+std::string SaveDataFactory::GetFullPath(Core::System& system, VirtualDir dir,
+ SaveDataSpaceId space, SaveDataType type, u64 title_id,
+ u128 user_id, u64 save_id) {
// According to switchbrew, if a save is of type SaveData and the title id field is 0, it should
// be interpreted as the title id of the current process.
if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) {
@@ -145,6 +176,17 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId s
}
}
+ // For compat with a future impl.
+ if (std::string future_path =
+ GetFutureSaveDataPath(space, type, title_id & ~(0xFFULL), user_id);
+ !future_path.empty()) {
+ // Check if this location exists, and prefer it over the old.
+ if (const auto future_dir = dir->GetDirectoryRelative(future_path); future_dir != nullptr) {
+ LOG_INFO(Service_FS, "Using save at new location: {}", future_path);
+ return future_path;
+ }
+ }
+
std::string out = GetSaveDataSpaceIdPath(space);
switch (type) {
@@ -167,7 +209,8 @@ std::string SaveDataFactory::GetFullPath(Core::System& system, SaveDataSpaceId s
SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
u128 user_id) const {
- const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
+ const auto path =
+ GetFullPath(system, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
const auto size_file = relative_dir->GetFile(SAVE_DATA_SIZE_FILENAME);
@@ -185,7 +228,8 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
SaveDataSize new_value) const {
- const auto path = GetFullPath(system, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
+ const auto path =
+ GetFullPath(system, dir, SaveDataSpaceId::NandUser, type, title_id, user_id, 0);
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
const auto size_file = relative_dir->CreateFile(SAVE_DATA_SIZE_FILENAME);
diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h
index a763b94c8..d3633ef03 100644
--- a/src/core/file_sys/savedata_factory.h
+++ b/src/core/file_sys/savedata_factory.h
@@ -95,8 +95,8 @@ public:
VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const;
static std::string GetSaveDataSpaceIdPath(SaveDataSpaceId space);
- static std::string GetFullPath(Core::System& system, SaveDataSpaceId space, SaveDataType type,
- u64 title_id, u128 user_id, u64 save_id);
+ static std::string GetFullPath(Core::System& system, VirtualDir dir, SaveDataSpaceId space,
+ SaveDataType type, u64 title_id, u128 user_id, u64 save_id);
SaveDataSize ReadSaveDataSize(SaveDataType type, u64 title_id, u128 user_id) const;
void WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp
index 90dd68ff1..b4081fc39 100644
--- a/src/core/frontend/framebuffer_layout.cpp
+++ b/src/core/frontend/framebuffer_layout.cpp
@@ -67,6 +67,8 @@ float EmulationAspectRatio(AspectRatio aspect, float window_aspect_ratio) {
return 3.0f / 4.0f;
case AspectRatio::R21_9:
return 9.0f / 21.0f;
+ case AspectRatio::R16_10:
+ return 10.0f / 16.0f;
case AspectRatio::StretchToWindow:
return window_aspect_ratio;
default:
diff --git a/src/core/frontend/framebuffer_layout.h b/src/core/frontend/framebuffer_layout.h
index 1561d994e..94683b30f 100644
--- a/src/core/frontend/framebuffer_layout.h
+++ b/src/core/frontend/framebuffer_layout.h
@@ -27,6 +27,7 @@ enum class AspectRatio {
Default,
R4_3,
R21_9,
+ R16_10,
StretchToWindow,
};
diff --git a/src/core/hardware_interrupt_manager.cpp b/src/core/hardware_interrupt_manager.cpp
deleted file mode 100644
index d08cc3315..000000000
--- a/src/core/hardware_interrupt_manager.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/core.h"
-#include "core/core_timing.h"
-#include "core/hardware_interrupt_manager.h"
-#include "core/hle/service/nvdrv/nvdrv_interface.h"
-#include "core/hle/service/sm/sm.h"
-
-namespace Core::Hardware {
-
-InterruptManager::InterruptManager(Core::System& system_in) : system(system_in) {
- gpu_interrupt_event = Core::Timing::CreateEvent(
- "GPUInterrupt",
- [this](std::uintptr_t message, u64 time,
- std::chrono::nanoseconds) -> std::optional<std::chrono::nanoseconds> {
- auto nvdrv = system.ServiceManager().GetService<Service::Nvidia::NVDRV>("nvdrv");
- const u32 syncpt = static_cast<u32>(message >> 32);
- const u32 value = static_cast<u32>(message);
- nvdrv->SignalGPUInterruptSyncpt(syncpt, value);
- return std::nullopt;
- });
-}
-
-InterruptManager::~InterruptManager() = default;
-
-void InterruptManager::GPUInterruptSyncpt(const u32 syncpoint_id, const u32 value) {
- const u64 msg = (static_cast<u64>(syncpoint_id) << 32ULL) | value;
- system.CoreTiming().ScheduleEvent(std::chrono::nanoseconds{10}, gpu_interrupt_event, msg);
-}
-
-} // namespace Core::Hardware
diff --git a/src/core/hardware_interrupt_manager.h b/src/core/hardware_interrupt_manager.h
deleted file mode 100644
index 5665c5918..000000000
--- a/src/core/hardware_interrupt_manager.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <memory>
-
-#include "common/common_types.h"
-
-namespace Core {
-class System;
-}
-
-namespace Core::Timing {
-struct EventType;
-}
-
-namespace Core::Hardware {
-
-class InterruptManager {
-public:
- explicit InterruptManager(Core::System& system);
- ~InterruptManager();
-
- void GPUInterruptSyncpt(u32 syncpoint_id, u32 value);
-
-private:
- Core::System& system;
- std::shared_ptr<Core::Timing::EventType> gpu_interrupt_event;
-};
-
-} // namespace Core::Hardware
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index 01c43be93..ec1364452 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -93,7 +93,7 @@ void EmulatedController::ReloadFromSettings() {
.body = GetNpadColor(player.body_color_left),
.button = GetNpadColor(player.button_color_left),
};
- controller.colors_state.left = {
+ controller.colors_state.right = {
.body = GetNpadColor(player.body_color_right),
.button = GetNpadColor(player.button_color_right),
};
@@ -131,13 +131,16 @@ void EmulatedController::LoadDevices() {
battery_params[RightIndex].Set("battery", true);
camera_params = Common::ParamPackage{"engine:camera,camera:1"};
+ nfc_params = Common::ParamPackage{"engine:virtual_amiibo,nfc:1"};
output_params[LeftIndex] = left_joycon;
output_params[RightIndex] = right_joycon;
output_params[2] = camera_params;
+ output_params[3] = nfc_params;
output_params[LeftIndex].Set("output", true);
output_params[RightIndex].Set("output", true);
output_params[2].Set("output", true);
+ output_params[3].Set("output", true);
LoadTASParams();
@@ -155,6 +158,7 @@ void EmulatedController::LoadDevices() {
std::transform(battery_params.begin(), battery_params.end(), battery_devices.begin(),
Common::Input::CreateDevice<Common::Input::InputDevice>);
camera_devices = Common::Input::CreateDevice<Common::Input::InputDevice>(camera_params);
+ nfc_devices = Common::Input::CreateDevice<Common::Input::InputDevice>(nfc_params);
std::transform(output_params.begin(), output_params.end(), output_devices.begin(),
Common::Input::CreateDevice<Common::Input::OutputDevice>);
@@ -284,6 +288,16 @@ void EmulatedController::ReloadInput() {
camera_devices->ForceUpdate();
}
+ if (nfc_devices) {
+ if (npad_id_type == NpadIdType::Handheld || npad_id_type == NpadIdType::Player1) {
+ nfc_devices->SetCallback({
+ .on_change =
+ [this](const Common::Input::CallbackStatus& callback) { SetNfc(callback); },
+ });
+ nfc_devices->ForceUpdate();
+ }
+ }
+
// Use a common UUID for TAS
static constexpr Common::UUID TAS_UUID = Common::UUID{
{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xA5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
@@ -339,6 +353,8 @@ void EmulatedController::UnloadInput() {
for (auto& stick : tas_stick_devices) {
stick.reset();
}
+ camera_devices.reset();
+ nfc_devices.reset();
}
void EmulatedController::EnableConfiguration() {
@@ -903,6 +919,25 @@ void EmulatedController::SetCamera(const Common::Input::CallbackStatus& callback
TriggerOnChange(ControllerTriggerType::IrSensor, true);
}
+void EmulatedController::SetNfc(const Common::Input::CallbackStatus& callback) {
+ std::unique_lock lock{mutex};
+ controller.nfc_values = TransformToNfc(callback);
+
+ if (is_configuring) {
+ lock.unlock();
+ TriggerOnChange(ControllerTriggerType::Nfc, false);
+ return;
+ }
+
+ controller.nfc_state = {
+ controller.nfc_values.state,
+ controller.nfc_values.data,
+ };
+
+ lock.unlock();
+ TriggerOnChange(ControllerTriggerType::Nfc, true);
+}
+
bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) {
if (device_index >= output_devices.size()) {
return false;
@@ -935,14 +970,7 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
Common::Input::VibrationError::None;
}
-bool EmulatedController::TestVibration(std::size_t device_index) {
- if (device_index >= output_devices.size()) {
- return false;
- }
- if (!output_devices[device_index]) {
- return false;
- }
-
+bool EmulatedController::IsVibrationEnabled(std::size_t device_index) {
const auto player_index = NpadIdTypeToIndex(npad_id_type);
const auto& player = Settings::values.players.GetValue()[player_index];
@@ -950,37 +978,27 @@ bool EmulatedController::TestVibration(std::size_t device_index) {
return false;
}
- const Common::Input::VibrationStatus test_vibration = {
- .low_amplitude = 0.001f,
- .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
- .high_amplitude = 0.001f,
- .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
- .type = Common::Input::VibrationAmplificationType::Test,
- };
-
- const Common::Input::VibrationStatus zero_vibration = {
- .low_amplitude = DEFAULT_VIBRATION_VALUE.low_amplitude,
- .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
- .high_amplitude = DEFAULT_VIBRATION_VALUE.high_amplitude,
- .high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
- .type = Common::Input::VibrationAmplificationType::Test,
- };
-
- // Send a slight vibration to test for rumble support
- output_devices[device_index]->SetVibration(test_vibration);
+ if (device_index >= output_devices.size()) {
+ return false;
+ }
- // Wait for about 15ms to ensure the controller is ready for the stop command
- std::this_thread::sleep_for(std::chrono::milliseconds(15));
+ if (!output_devices[device_index]) {
+ return false;
+ }
- // Stop any vibration and return the result
- return output_devices[device_index]->SetVibration(zero_vibration) ==
- Common::Input::VibrationError::None;
+ return output_devices[device_index]->IsVibrationEnabled();
}
bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) {
LOG_INFO(Service_HID, "Set polling mode {}", polling_mode);
auto& output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)];
- return output_device->SetPollingMode(polling_mode) == Common::Input::PollingError::None;
+ auto& nfc_output_device = output_devices[3];
+
+ const auto virtual_nfc_result = nfc_output_device->SetPollingMode(polling_mode);
+ const auto mapped_nfc_result = output_device->SetPollingMode(polling_mode);
+
+ return virtual_nfc_result == Common::Input::PollingError::None ||
+ mapped_nfc_result == Common::Input::PollingError::None;
}
bool EmulatedController::SetCameraFormat(
@@ -1000,6 +1018,33 @@ bool EmulatedController::SetCameraFormat(
camera_format)) == Common::Input::CameraError::None;
}
+bool EmulatedController::HasNfc() const {
+ const auto& nfc_output_device = output_devices[3];
+
+ switch (npad_type) {
+ case NpadStyleIndex::JoyconRight:
+ case NpadStyleIndex::JoyconDual:
+ case NpadStyleIndex::ProController:
+ case NpadStyleIndex::Handheld:
+ break;
+ default:
+ return false;
+ }
+
+ const bool has_virtual_nfc =
+ npad_id_type == NpadIdType::Player1 || npad_id_type == NpadIdType::Handheld;
+ const bool is_virtual_nfc_supported =
+ nfc_output_device->SupportsNfc() != Common::Input::NfcState::NotSupported;
+
+ return is_connected && (has_virtual_nfc && is_virtual_nfc_supported);
+}
+
+bool EmulatedController::WriteNfc(const std::vector<u8>& data) {
+ auto& nfc_output_device = output_devices[3];
+
+ return nfc_output_device->WriteNfcData(data) == Common::Input::NfcState::Success;
+}
+
void EmulatedController::SetLedPattern() {
for (auto& device : output_devices) {
if (!device) {
@@ -1091,27 +1136,27 @@ bool EmulatedController::IsControllerSupported(bool use_temporary_value) const {
const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type;
switch (type) {
case NpadStyleIndex::ProController:
- return supported_style_tag.fullkey;
+ return supported_style_tag.fullkey.As<bool>();
case NpadStyleIndex::Handheld:
- return supported_style_tag.handheld;
+ return supported_style_tag.handheld.As<bool>();
case NpadStyleIndex::JoyconDual:
- return supported_style_tag.joycon_dual;
+ return supported_style_tag.joycon_dual.As<bool>();
case NpadStyleIndex::JoyconLeft:
- return supported_style_tag.joycon_left;
+ return supported_style_tag.joycon_left.As<bool>();
case NpadStyleIndex::JoyconRight:
- return supported_style_tag.joycon_right;
+ return supported_style_tag.joycon_right.As<bool>();
case NpadStyleIndex::GameCube:
- return supported_style_tag.gamecube;
+ return supported_style_tag.gamecube.As<bool>();
case NpadStyleIndex::Pokeball:
- return supported_style_tag.palma;
+ return supported_style_tag.palma.As<bool>();
case NpadStyleIndex::NES:
- return supported_style_tag.lark;
+ return supported_style_tag.lark.As<bool>();
case NpadStyleIndex::SNES:
- return supported_style_tag.lucia;
+ return supported_style_tag.lucia.As<bool>();
case NpadStyleIndex::N64:
- return supported_style_tag.lagoon;
+ return supported_style_tag.lagoon.As<bool>();
case NpadStyleIndex::SegaGenesis:
- return supported_style_tag.lager;
+ return supported_style_tag.lager.As<bool>();
default:
return false;
}
@@ -1167,12 +1212,6 @@ bool EmulatedController::IsConnected(bool get_temporary_value) const {
return is_connected;
}
-bool EmulatedController::IsVibrationEnabled() const {
- const auto player_index = NpadIdTypeToIndex(npad_id_type);
- const auto& player = Settings::values.players.GetValue()[player_index];
- return player.vibration_enabled;
-}
-
NpadIdType EmulatedController::GetNpadIdType() const {
std::scoped_lock lock{mutex};
return npad_id_type;
@@ -1363,6 +1402,11 @@ const CameraState& EmulatedController::GetCamera() const {
return controller.camera_state;
}
+const NfcState& EmulatedController::GetNfc() const {
+ std::scoped_lock lock{mutex};
+ return controller.nfc_state;
+}
+
NpadColor EmulatedController::GetNpadColor(u32 color) {
return {
.r = static_cast<u8>((color >> 16) & 0xFF),
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h
index c3aa8f9d3..d004ca56a 100644
--- a/src/core/hid/emulated_controller.h
+++ b/src/core/hid/emulated_controller.h
@@ -20,7 +20,7 @@
namespace Core::HID {
const std::size_t max_emulated_controllers = 2;
-const std::size_t output_devices = 3;
+const std::size_t output_devices_size = 4;
struct ControllerMotionInfo {
Common::Input::MotionStatus raw_status{};
MotionInput emulated{};
@@ -37,7 +37,8 @@ using TriggerDevices =
using BatteryDevices =
std::array<std::unique_ptr<Common::Input::InputDevice>, max_emulated_controllers>;
using CameraDevices = std::unique_ptr<Common::Input::InputDevice>;
-using OutputDevices = std::array<std::unique_ptr<Common::Input::OutputDevice>, output_devices>;
+using NfcDevices = std::unique_ptr<Common::Input::InputDevice>;
+using OutputDevices = std::array<std::unique_ptr<Common::Input::OutputDevice>, output_devices_size>;
using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>;
using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>;
@@ -45,7 +46,8 @@ using ControllerMotionParams = std::array<Common::ParamPackage, Settings::Native
using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>;
using BatteryParams = std::array<Common::ParamPackage, max_emulated_controllers>;
using CameraParams = Common::ParamPackage;
-using OutputParams = std::array<Common::ParamPackage, output_devices>;
+using NfcParams = Common::ParamPackage;
+using OutputParams = std::array<Common::ParamPackage, output_devices_size>;
using ButtonValues = std::array<Common::Input::ButtonStatus, Settings::NativeButton::NumButtons>;
using SticksValues = std::array<Common::Input::StickStatus, Settings::NativeAnalog::NumAnalogs>;
@@ -55,6 +57,7 @@ using ControllerMotionValues = std::array<ControllerMotionInfo, Settings::Native
using ColorValues = std::array<Common::Input::BodyColorStatus, max_emulated_controllers>;
using BatteryValues = std::array<Common::Input::BatteryStatus, max_emulated_controllers>;
using CameraValues = Common::Input::CameraStatus;
+using NfcValues = Common::Input::NfcStatus;
using VibrationValues = std::array<Common::Input::VibrationStatus, max_emulated_controllers>;
struct AnalogSticks {
@@ -80,6 +83,11 @@ struct CameraState {
std::size_t sample{};
};
+struct NfcState {
+ Common::Input::NfcState state{};
+ std::vector<u8> data{};
+};
+
struct ControllerMotion {
Common::Vec3f accel{};
Common::Vec3f gyro{};
@@ -107,6 +115,7 @@ struct ControllerStatus {
BatteryValues battery_values{};
VibrationValues vibration_values{};
CameraValues camera_values{};
+ NfcValues nfc_values{};
// Data for HID serices
HomeButtonState home_button_state{};
@@ -119,6 +128,7 @@ struct ControllerStatus {
ControllerColors colors_state{};
BatteryLevelState battery_state{};
CameraState camera_state{};
+ NfcState nfc_state{};
};
enum class ControllerTriggerType {
@@ -130,6 +140,7 @@ enum class ControllerTriggerType {
Battery,
Vibration,
IrSensor,
+ Nfc,
Connected,
Disconnected,
Type,
@@ -195,9 +206,6 @@ public:
*/
bool IsConnected(bool get_temporary_value = false) const;
- /// Returns true if vibration is enabled
- bool IsVibrationEnabled() const;
-
/// Removes all callbacks created from input devices
void UnloadInput();
@@ -315,6 +323,9 @@ public:
/// Returns the latest camera status from the controller
const CameraState& GetCamera() const;
+ /// Returns the latest ntag status from the controller
+ const NfcState& GetNfc() const;
+
/**
* Sends a specific vibration to the output device
* @return true if vibration had no errors
@@ -325,7 +336,7 @@ public:
* Sends a small vibration to the output device
* @return true if SetVibration was successfull
*/
- bool TestVibration(std::size_t device_index);
+ bool IsVibrationEnabled(std::size_t device_index);
/**
* Sets the desired data to be polled from a controller
@@ -341,6 +352,12 @@ public:
*/
bool SetCameraFormat(Core::IrSensor::ImageTransferProcessorFormat camera_format);
+ /// Returns true if the device has nfc support
+ bool HasNfc() const;
+
+ /// Returns true if the nfc tag was written
+ bool WriteNfc(const std::vector<u8>& data);
+
/// Returns the led pattern corresponding to this emulated controller
LedPattern GetLedPattern() const;
@@ -425,6 +442,12 @@ private:
void SetCamera(const Common::Input::CallbackStatus& callback);
/**
+ * Updates the nfc status of the controller
+ * @param callback A CallbackStatus containing the nfc status
+ */
+ void SetNfc(const Common::Input::CallbackStatus& callback);
+
+ /**
* Converts a color format from bgra to rgba
* @param color in bgra format
* @return NpadColor in rgba format
@@ -458,6 +481,7 @@ private:
TriggerParams trigger_params;
BatteryParams battery_params;
CameraParams camera_params;
+ NfcParams nfc_params;
OutputParams output_params;
ButtonDevices button_devices;
@@ -466,6 +490,7 @@ private:
TriggerDevices trigger_devices;
BatteryDevices battery_devices;
CameraDevices camera_devices;
+ NfcDevices nfc_devices;
OutputDevices output_devices;
// TAS related variables
diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp
index 52fb69e9c..5d8b75b50 100644
--- a/src/core/hid/input_converter.cpp
+++ b/src/core/hid/input_converter.cpp
@@ -277,7 +277,10 @@ Common::Input::CameraStatus TransformToCamera(const Common::Input::CallbackStatu
Common::Input::CameraStatus camera{};
switch (callback.type) {
case Common::Input::InputType::IrSensor:
- camera = callback.camera_status;
+ camera = {
+ .format = callback.camera_status,
+ .data = callback.raw_data,
+ };
break;
default:
LOG_ERROR(Input, "Conversion from type {} to camera not implemented", callback.type);
@@ -287,6 +290,23 @@ Common::Input::CameraStatus TransformToCamera(const Common::Input::CallbackStatu
return camera;
}
+Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& callback) {
+ Common::Input::NfcStatus nfc{};
+ switch (callback.type) {
+ case Common::Input::InputType::Nfc:
+ nfc = {
+ .state = callback.nfc_status,
+ .data = callback.raw_data,
+ };
+ break;
+ default:
+ LOG_ERROR(Input, "Conversion from type {} to NFC not implemented", callback.type);
+ break;
+ }
+
+ return nfc;
+}
+
void SanitizeAnalog(Common::Input::AnalogStatus& analog, bool clamp_value) {
const auto& properties = analog.properties;
float& raw_value = analog.raw_value;
diff --git a/src/core/hid/input_converter.h b/src/core/hid/input_converter.h
index 143c50cc0..b7eb6e660 100644
--- a/src/core/hid/input_converter.h
+++ b/src/core/hid/input_converter.h
@@ -85,6 +85,14 @@ Common::Input::AnalogStatus TransformToAnalog(const Common::Input::CallbackStatu
Common::Input::CameraStatus TransformToCamera(const Common::Input::CallbackStatus& callback);
/**
+ * Converts raw input data into a valid nfc status.
+ *
+ * @param callback Supported callbacks: Nfc.
+ * @return A valid CameraObject object.
+ */
+Common::Input::NfcStatus TransformToNfc(const Common::Input::CallbackStatus& callback);
+
+/**
* Converts raw analog data into a valid analog value
* @param analog An analog object containing raw data and properties
* @param clamp_value determines if the value needs to be clamped between -1.0f and 1.0f.
diff --git a/src/core/hid/irs_types.h b/src/core/hid/irs_types.h
index 88c5b016d..0d1bfe53f 100644
--- a/src/core/hid/irs_types.h
+++ b/src/core/hid/irs_types.h
@@ -14,7 +14,7 @@ enum class CameraAmbientNoiseLevel : u32 {
Low,
Medium,
High,
- Unkown3, // This level can't be reached
+ Unknown3, // This level can't be reached
};
// This is nn::irsensor::CameraLightTarget
@@ -75,9 +75,9 @@ enum class IrCameraStatus : u32 {
enum class IrCameraInternalStatus : u32 {
Stopped,
FirmwareUpdateNeeded,
- Unkown2,
- Unkown3,
- Unkown4,
+ Unknown2,
+ Unknown3,
+ Unknown4,
FirmwareVersionRequested,
FirmwareVersionIsInvalid,
Ready,
@@ -121,20 +121,20 @@ enum class IrSensorFunctionLevel : u8 {
// This is nn::irsensor::MomentProcessorPreprocess
enum class MomentProcessorPreprocess : u32 {
- Unkown0,
- Unkown1,
+ Unknown0,
+ Unknown1,
};
// This is nn::irsensor::PackedMomentProcessorPreprocess
enum class PackedMomentProcessorPreprocess : u8 {
- Unkown0,
- Unkown1,
+ Unknown0,
+ Unknown1,
};
// This is nn::irsensor::PointingStatus
enum class PointingStatus : u32 {
- Unkown0,
- Unkown1,
+ Unknown0,
+ Unknown1,
};
struct IrsRect {
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index d631c0357..3bb111748 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -86,13 +86,13 @@ public:
u32 num_domain_objects{};
const bool always_move_handles{
(static_cast<u32>(flags) & static_cast<u32>(Flags::AlwaysMoveHandles)) != 0};
- if (!ctx.Session()->IsDomain() || always_move_handles) {
+ if (!ctx.GetManager()->IsDomain() || always_move_handles) {
num_handles_to_move = num_objects_to_move;
} else {
num_domain_objects = num_objects_to_move;
}
- if (ctx.Session()->IsDomain()) {
+ if (ctx.GetManager()->IsDomain()) {
raw_data_size +=
static_cast<u32>(sizeof(DomainMessageHeader) / sizeof(u32) + num_domain_objects);
ctx.write_size += num_domain_objects;
@@ -125,7 +125,7 @@ public:
if (!ctx.IsTipc()) {
AlignWithPadding();
- if (ctx.Session()->IsDomain() && ctx.HasDomainMessageHeader()) {
+ if (ctx.GetManager()->IsDomain() && ctx.HasDomainMessageHeader()) {
IPC::DomainMessageHeader domain_header{};
domain_header.num_objects = num_domain_objects;
PushRaw(domain_header);
@@ -145,7 +145,7 @@ public:
template <class T>
void PushIpcInterface(std::shared_ptr<T> iface) {
- if (context->Session()->IsDomain()) {
+ if (context->GetManager()->IsDomain()) {
context->AddDomainObject(std::move(iface));
} else {
kernel.CurrentProcess()->GetResourceLimit()->Reserve(
@@ -153,9 +153,10 @@ public:
auto* session = Kernel::KSession::Create(kernel);
session->Initialize(nullptr, iface->GetServiceName());
+ iface->RegisterSession(&session->GetServerSession(),
+ std::make_shared<Kernel::SessionRequestManager>(kernel));
context->AddMoveObject(&session->GetClientSession());
- iface->ClientConnected(&session->GetServerSession());
}
}
@@ -385,7 +386,7 @@ public:
template <class T>
std::weak_ptr<T> PopIpcInterface() {
- ASSERT(context->Session()->IsDomain());
+ ASSERT(context->GetManager()->IsDomain());
ASSERT(context->GetDomainMessageHeader().input_object_count > 0);
return context->GetDomainHandler<T>(Pop<u32>() - 1);
}
@@ -404,7 +405,7 @@ inline s32 RequestParser::Pop() {
}
// Ignore the -Wclass-memaccess warning on memcpy for non-trivially default constructible objects.
-#if defined(__GNUC__)
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wclass-memaccess"
#endif
@@ -415,7 +416,7 @@ void RequestParser::PopRaw(T& value) {
std::memcpy(&value, cmdbuf + index, sizeof(T));
index += (sizeof(T) + 3) / 4; // round up to word length
}
-#if defined(__GNUC__)
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
#pragma GCC diagnostic pop
#endif
diff --git a/src/core/hle/kernel/global_scheduler_context.cpp b/src/core/hle/kernel/global_scheduler_context.cpp
index 65576b8c4..fd911a3a5 100644
--- a/src/core/hle/kernel/global_scheduler_context.cpp
+++ b/src/core/hle/kernel/global_scheduler_context.cpp
@@ -49,4 +49,26 @@ bool GlobalSchedulerContext::IsLocked() const {
return scheduler_lock.IsLockedByCurrentThread();
}
+void GlobalSchedulerContext::RegisterDummyThreadForWakeup(KThread* thread) {
+ ASSERT(IsLocked());
+
+ woken_dummy_threads.insert(thread);
+}
+
+void GlobalSchedulerContext::UnregisterDummyThreadForWakeup(KThread* thread) {
+ ASSERT(IsLocked());
+
+ woken_dummy_threads.erase(thread);
+}
+
+void GlobalSchedulerContext::WakeupWaitingDummyThreads() {
+ ASSERT(IsLocked());
+
+ for (auto* thread : woken_dummy_threads) {
+ thread->DummyThreadEndWait();
+ }
+
+ woken_dummy_threads.clear();
+}
+
} // namespace Kernel
diff --git a/src/core/hle/kernel/global_scheduler_context.h b/src/core/hle/kernel/global_scheduler_context.h
index 67bb9852d..220ed6192 100644
--- a/src/core/hle/kernel/global_scheduler_context.h
+++ b/src/core/hle/kernel/global_scheduler_context.h
@@ -4,6 +4,7 @@
#pragma once
#include <atomic>
+#include <set>
#include <vector>
#include "common/common_types.h"
@@ -58,6 +59,10 @@ public:
/// Returns true if the global scheduler lock is acquired
bool IsLocked() const;
+ void UnregisterDummyThreadForWakeup(KThread* thread);
+ void RegisterDummyThreadForWakeup(KThread* thread);
+ void WakeupWaitingDummyThreads();
+
[[nodiscard]] LockType& SchedulerLock() {
return scheduler_lock;
}
@@ -76,6 +81,9 @@ private:
KSchedulerPriorityQueue priority_queue;
LockType scheduler_lock;
+ /// Lists dummy threads pending wakeup on lock release
+ std::set<KThread*> woken_dummy_threads;
+
/// Lists all thread ids that aren't deleted/etc.
std::vector<KThread*> thread_list;
std::mutex global_list_guard;
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 5b3feec66..fd354d484 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -16,9 +16,11 @@
#include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/k_handle_table.h"
#include "core/hle/kernel/k_process.h"
+#include "core/hle/kernel/k_server_port.h"
#include "core/hle/kernel/k_server_session.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/service_thread.h"
#include "core/memory.h"
namespace Kernel {
@@ -34,7 +36,21 @@ SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* se
}
SessionRequestHandler::~SessionRequestHandler() {
- kernel.ReleaseServiceThread(service_thread);
+ kernel.ReleaseServiceThread(service_thread.lock());
+}
+
+void SessionRequestHandler::AcceptSession(KServerPort* server_port) {
+ auto* server_session = server_port->AcceptSession();
+ ASSERT(server_session != nullptr);
+
+ RegisterSession(server_session, std::make_shared<SessionRequestManager>(kernel));
+}
+
+void SessionRequestHandler::RegisterSession(KServerSession* server_session,
+ std::shared_ptr<SessionRequestManager> manager) {
+ manager->SetSessionHandler(shared_from_this());
+ service_thread.lock()->RegisterServerSession(server_session, manager);
+ server_session->Close();
}
SessionRequestManager::SessionRequestManager(KernelCore& kernel_) : kernel{kernel_} {}
@@ -56,15 +72,77 @@ bool SessionRequestManager::HasSessionRequestHandler(const HLERequestContext& co
}
}
-void SessionRequestHandler::ClientConnected(KServerSession* session) {
- session->ClientConnected(shared_from_this());
+Result SessionRequestManager::CompleteSyncRequest(KServerSession* server_session,
+ HLERequestContext& context) {
+ Result result = ResultSuccess;
+
+ // If the session has been converted to a domain, handle the domain request
+ if (this->HasSessionRequestHandler(context)) {
+ if (IsDomain() && context.HasDomainMessageHeader()) {
+ result = HandleDomainSyncRequest(server_session, context);
+ // If there is no domain header, the regular session handler is used
+ } else if (this->HasSessionHandler()) {
+ // If this manager has an associated HLE handler, forward the request to it.
+ result = this->SessionHandler().HandleSyncRequest(*server_session, context);
+ }
+ } else {
+ ASSERT_MSG(false, "Session handler is invalid, stubbing response!");
+ IPC::ResponseBuilder rb(context, 2);
+ rb.Push(ResultSuccess);
+ }
+
+ if (convert_to_domain) {
+ ASSERT_MSG(!IsDomain(), "ServerSession is already a domain instance.");
+ this->ConvertToDomain();
+ convert_to_domain = false;
+ }
- // Ensure our server session is tracked globally.
- kernel.RegisterServerObject(session);
+ return result;
}
-void SessionRequestHandler::ClientDisconnected(KServerSession* session) {
- session->ClientDisconnected();
+Result SessionRequestManager::HandleDomainSyncRequest(KServerSession* server_session,
+ HLERequestContext& context) {
+ if (!context.HasDomainMessageHeader()) {
+ return ResultSuccess;
+ }
+
+ // Set domain handlers in HLE context, used for domain objects (IPC interfaces) as inputs
+ ASSERT(context.GetManager().get() == this);
+
+ // If there is a DomainMessageHeader, then this is CommandType "Request"
+ const auto& domain_message_header = context.GetDomainMessageHeader();
+ const u32 object_id{domain_message_header.object_id};
+ switch (domain_message_header.command) {
+ case IPC::DomainMessageHeader::CommandType::SendMessage:
+ if (object_id > this->DomainHandlerCount()) {
+ LOG_CRITICAL(IPC,
+ "object_id {} is too big! This probably means a recent service call "
+ "needed to return a new interface!",
+ object_id);
+ ASSERT(false);
+ return ResultSuccess; // Ignore error if asserts are off
+ }
+ if (auto strong_ptr = this->DomainHandler(object_id - 1).lock()) {
+ return strong_ptr->HandleSyncRequest(*server_session, context);
+ } else {
+ ASSERT(false);
+ return ResultSuccess;
+ }
+
+ case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
+ LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x{:08X}", object_id);
+
+ this->CloseDomainHandler(object_id - 1);
+
+ IPC::ResponseBuilder rb{context, 2};
+ rb.Push(ResultSuccess);
+ return ResultSuccess;
+ }
+ }
+
+ LOG_CRITICAL(IPC, "Unknown domain command={}", domain_message_header.command.Value());
+ ASSERT(false);
+ return ResultSuccess;
}
HLERequestContext::HLERequestContext(KernelCore& kernel_, Core::Memory::Memory& memory_,
@@ -126,7 +204,7 @@ void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32
// Padding to align to 16 bytes
rp.AlignWithPadding();
- if (Session()->IsDomain() &&
+ if (GetManager()->IsDomain() &&
((command_header->type == IPC::CommandType::Request ||
command_header->type == IPC::CommandType::RequestWithContext) ||
!incoming)) {
@@ -135,7 +213,7 @@ void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32
if (incoming || domain_message_header) {
domain_message_header = rp.PopRaw<IPC::DomainMessageHeader>();
} else {
- if (Session()->IsDomain()) {
+ if (GetManager()->IsDomain()) {
LOG_WARNING(IPC, "Domain request has no DomainMessageHeader!");
}
}
@@ -228,12 +306,11 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer(KThread& requesting_threa
// Write the domain objects to the command buffer, these go after the raw untranslated data.
// TODO(Subv): This completely ignores C buffers.
- if (Session()->IsDomain()) {
+ if (GetManager()->IsDomain()) {
current_offset = domain_offset - static_cast<u32>(outgoing_domain_objects.size());
- for (const auto& object : outgoing_domain_objects) {
- server_session->AppendDomainHandler(object);
- cmd_buf[current_offset++] =
- static_cast<u32_le>(server_session->NumDomainRequestHandlers());
+ for (auto& object : outgoing_domain_objects) {
+ GetManager()->AppendDomainHandler(std::move(object));
+ cmd_buf[current_offset++] = static_cast<u32_le>(GetManager()->DomainHandlerCount());
}
}
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index 99265ce90..67da8e7e1 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -43,13 +43,15 @@ class Domain;
class HLERequestContext;
class KAutoObject;
class KernelCore;
+class KEvent;
class KHandleTable;
+class KServerPort;
class KProcess;
class KServerSession;
class KThread;
class KReadableEvent;
class KSession;
-class KWritableEvent;
+class SessionRequestManager;
class ServiceThread;
enum class ThreadWakeupReason;
@@ -76,19 +78,9 @@ public:
virtual Result HandleSyncRequest(Kernel::KServerSession& session,
Kernel::HLERequestContext& context) = 0;
- /**
- * Signals that a client has just connected to this HLE handler and keeps the
- * associated ServerSession alive for the duration of the connection.
- * @param server_session Owning pointer to the ServerSession associated with the connection.
- */
- void ClientConnected(KServerSession* session);
-
- /**
- * Signals that a client has just disconnected from this HLE handler and releases the
- * associated ServerSession.
- * @param server_session ServerSession associated with the connection.
- */
- void ClientDisconnected(KServerSession* session);
+ void AcceptSession(KServerPort* server_port);
+ void RegisterSession(KServerSession* server_session,
+ std::shared_ptr<SessionRequestManager> manager);
std::weak_ptr<ServiceThread> GetServiceThread() const {
return service_thread;
@@ -121,6 +113,10 @@ public:
is_domain = true;
}
+ void ConvertToDomainOnRequestEnd() {
+ convert_to_domain = true;
+ }
+
std::size_t DomainHandlerCount() const {
return domain_handlers.size();
}
@@ -164,7 +160,11 @@ public:
bool HasSessionRequestHandler(const HLERequestContext& context) const;
+ Result HandleDomainSyncRequest(KServerSession* server_session, HLERequestContext& context);
+ Result CompleteSyncRequest(KServerSession* server_session, HLERequestContext& context);
+
private:
+ bool convert_to_domain{};
bool is_domain{};
SessionRequestHandlerPtr session_handler;
std::vector<SessionRequestHandlerPtr> domain_handlers;
@@ -295,7 +295,7 @@ public:
*/
template <typename T, typename = std::enable_if_t<!std::is_pointer_v<T>>>
std::size_t WriteBuffer(const T& data, std::size_t buffer_index = 0) const {
- if constexpr (Common::IsSTLContainer<T>) {
+ if constexpr (Common::IsContiguousContainer<T>) {
using ContiguousType = typename T::value_type;
static_assert(std::is_trivially_copyable_v<ContiguousType>,
"Container to WriteBuffer must contain trivially copyable objects");
@@ -341,11 +341,11 @@ public:
template <typename T>
std::shared_ptr<T> GetDomainHandler(std::size_t index) const {
- return std::static_pointer_cast<T>(manager.lock()->DomainHandler(index).lock());
+ return std::static_pointer_cast<T>(GetManager()->DomainHandler(index).lock());
}
void SetSessionRequestManager(std::weak_ptr<SessionRequestManager> manager_) {
- manager = std::move(manager_);
+ manager = manager_;
}
std::string Description() const;
@@ -354,6 +354,10 @@ public:
return *thread;
}
+ std::shared_ptr<SessionRequestManager> GetManager() const {
+ return manager.lock();
+ }
+
private:
friend class IPC::ResponseBuilder;
@@ -387,7 +391,7 @@ private:
u32 handles_offset{};
u32 domain_offset{};
- std::weak_ptr<SessionRequestManager> manager;
+ std::weak_ptr<SessionRequestManager> manager{};
KernelCore& kernel;
Core::Memory::Memory& memory;
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp
index 9b6b284d0..477e4e407 100644
--- a/src/core/hle/kernel/init/init_slab_setup.cpp
+++ b/src/core/hle/kernel/init/init_slab_setup.cpp
@@ -18,6 +18,7 @@
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/k_session.h"
+#include "core/hle/kernel/k_session_request.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_shared_memory_info.h"
#include "core/hle/kernel/k_system_control.h"
@@ -34,6 +35,7 @@ namespace Kernel::Init {
HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) \
HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \
HANDLER(KPort, (SLAB_COUNT(KPort)), ##__VA_ARGS__) \
+ HANDLER(KSessionRequest, (SLAB_COUNT(KSession) * 2), ##__VA_ARGS__) \
HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__) \
HANDLER(KSharedMemoryInfo, (SLAB_COUNT(KSharedMemory) * 8), ##__VA_ARGS__) \
HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ##__VA_ARGS__) \
@@ -94,8 +96,8 @@ VAddr InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, VAd
// TODO(bunnei): Fix this once we support the kernel virtual memory layout.
if (size > 0) {
- void* backing_kernel_memory{
- system.DeviceMemory().GetPointer(TranslateSlabAddrToPhysical(memory_layout, start))};
+ void* backing_kernel_memory{system.DeviceMemory().GetPointer<void>(
+ TranslateSlabAddrToPhysical(memory_layout, start))};
const KMemoryRegion* region = memory_layout.FindVirtual(start + size - 1);
ASSERT(region != nullptr);
@@ -181,7 +183,7 @@ void InitializeKPageBufferSlabHeap(Core::System& system) {
ASSERT(slab_address != 0);
// Initialize the slabheap.
- KPageBuffer::InitializeSlabHeap(kernel, system.DeviceMemory().GetPointer(slab_address),
+ KPageBuffer::InitializeSlabHeap(kernel, system.DeviceMemory().GetPointer<void>(slab_address),
slab_size);
}
diff --git a/src/core/hle/kernel/k_class_token.cpp b/src/core/hle/kernel/k_class_token.cpp
index cc2a0f7ca..10265c23c 100644
--- a/src/core/hle/kernel/k_class_token.cpp
+++ b/src/core/hle/kernel/k_class_token.cpp
@@ -18,7 +18,6 @@
#include "core/hle/kernel/k_synchronization_object.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/k_transfer_memory.h"
-#include "core/hle/kernel/k_writable_event.h"
namespace Kernel {
@@ -42,13 +41,12 @@ static_assert(ClassToken<KPort> == 0b10000101'00000000);
static_assert(ClassToken<KSession> == 0b00011001'00000000);
static_assert(ClassToken<KSharedMemory> == 0b00101001'00000000);
static_assert(ClassToken<KEvent> == 0b01001001'00000000);
-static_assert(ClassToken<KWritableEvent> == 0b10001001'00000000);
// static_assert(ClassToken<KLightClientSession> == 0b00110001'00000000);
// static_assert(ClassToken<KLightServerSession> == 0b01010001'00000000);
-static_assert(ClassToken<KTransferMemory> == 0b10010001'00000000);
+static_assert(ClassToken<KTransferMemory> == 0b01010001'00000000);
// static_assert(ClassToken<KDeviceAddressSpace> == 0b01100001'00000000);
// static_assert(ClassToken<KSessionRequest> == 0b10100001'00000000);
-static_assert(ClassToken<KCodeMemory> == 0b11000001'00000000);
+static_assert(ClassToken<KCodeMemory> == 0b10100001'00000000);
// Ensure that the token hierarchy is correct.
@@ -73,13 +71,12 @@ static_assert(ClassToken<KPort> == ((0b10000101 << 8) | ClassToken<KAutoObject>)
static_assert(ClassToken<KSession> == ((0b00011001 << 8) | ClassToken<KAutoObject>));
static_assert(ClassToken<KSharedMemory> == ((0b00101001 << 8) | ClassToken<KAutoObject>));
static_assert(ClassToken<KEvent> == ((0b01001001 << 8) | ClassToken<KAutoObject>));
-static_assert(ClassToken<KWritableEvent> == ((0b10001001 << 8) | ClassToken<KAutoObject>));
// static_assert(ClassToken<KLightClientSession> == ((0b00110001 << 8) | ClassToken<KAutoObject>));
// static_assert(ClassToken<KLightServerSession> == ((0b01010001 << 8) | ClassToken<KAutoObject>));
-static_assert(ClassToken<KTransferMemory> == ((0b10010001 << 8) | ClassToken<KAutoObject>));
+static_assert(ClassToken<KTransferMemory> == ((0b01010001 << 8) | ClassToken<KAutoObject>));
// static_assert(ClassToken<KDeviceAddressSpace> == ((0b01100001 << 8) | ClassToken<KAutoObject>));
// static_assert(ClassToken<KSessionRequest> == ((0b10100001 << 8) | ClassToken<KAutoObject>));
-static_assert(ClassToken<KCodeMemory> == ((0b11000001 << 8) | ClassToken<KAutoObject>));
+static_assert(ClassToken<KCodeMemory> == ((0b10100001 << 8) | ClassToken<KAutoObject>));
// Ensure that the token hierarchy reflects the class hierarchy.
@@ -110,7 +107,6 @@ static_assert(std::is_final_v<KPort> && std::is_base_of_v<KAutoObject, KPort>);
static_assert(std::is_final_v<KSession> && std::is_base_of_v<KAutoObject, KSession>);
static_assert(std::is_final_v<KSharedMemory> && std::is_base_of_v<KAutoObject, KSharedMemory>);
static_assert(std::is_final_v<KEvent> && std::is_base_of_v<KAutoObject, KEvent>);
-static_assert(std::is_final_v<KWritableEvent> && std::is_base_of_v<KAutoObject, KWritableEvent>);
// static_assert(std::is_final_v<KLightClientSession> &&
// std::is_base_of_v<KAutoObject, KLightClientSession>);
// static_assert(std::is_final_v<KLightServerSession> &&
diff --git a/src/core/hle/kernel/k_class_token.h b/src/core/hle/kernel/k_class_token.h
index c9001ae3d..ab20e00ff 100644
--- a/src/core/hle/kernel/k_class_token.h
+++ b/src/core/hle/kernel/k_class_token.h
@@ -101,7 +101,6 @@ public:
KSession,
KSharedMemory,
KEvent,
- KWritableEvent,
KLightClientSession,
KLightServerSession,
KTransferMemory,
diff --git a/src/core/hle/kernel/k_client_port.cpp b/src/core/hle/kernel/k_client_port.cpp
index 3cb22ff4d..eaa2e094c 100644
--- a/src/core/hle/kernel/k_client_port.cpp
+++ b/src/core/hle/kernel/k_client_port.cpp
@@ -58,8 +58,7 @@ bool KClientPort::IsSignaled() const {
return num_sessions < max_sessions;
}
-Result KClientPort::CreateSession(KClientSession** out,
- std::shared_ptr<SessionRequestManager> session_manager) {
+Result KClientPort::CreateSession(KClientSession** out) {
// Reserve a new session from the resource limit.
KScopedResourceReservation session_reservation(kernel.CurrentProcess()->GetResourceLimit(),
LimitableResource::Sessions);
@@ -104,7 +103,7 @@ Result KClientPort::CreateSession(KClientSession** out,
}
// Initialize the session.
- session->Initialize(this, parent->GetName(), session_manager);
+ session->Initialize(this, parent->GetName());
// Commit the session reservation.
session_reservation.Commit();
diff --git a/src/core/hle/kernel/k_client_port.h b/src/core/hle/kernel/k_client_port.h
index e17eff28f..81046fb86 100644
--- a/src/core/hle/kernel/k_client_port.h
+++ b/src/core/hle/kernel/k_client_port.h
@@ -52,8 +52,7 @@ public:
void Destroy() override;
bool IsSignaled() const override;
- Result CreateSession(KClientSession** out,
- std::shared_ptr<SessionRequestManager> session_manager = nullptr);
+ Result CreateSession(KClientSession** out);
private:
std::atomic<s32> num_sessions{};
diff --git a/src/core/hle/kernel/k_client_session.cpp b/src/core/hle/kernel/k_client_session.cpp
index b2a887b14..b4197a8d5 100644
--- a/src/core/hle/kernel/k_client_session.cpp
+++ b/src/core/hle/kernel/k_client_session.cpp
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include "common/scope_exit.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/k_client_session.h"
#include "core/hle/kernel/k_server_session.h"
@@ -10,6 +11,8 @@
namespace Kernel {
+static constexpr u32 MessageBufferSize = 0x100;
+
KClientSession::KClientSession(KernelCore& kernel_)
: KAutoObjectWithSlabHeapAndContainer{kernel_} {}
KClientSession::~KClientSession() = default;
@@ -21,10 +24,17 @@ void KClientSession::Destroy() {
void KClientSession::OnServerClosed() {}
-Result KClientSession::SendSyncRequest(KThread* thread, Core::Memory::Memory& memory,
- Core::Timing::CoreTiming& core_timing) {
- // Signal the server session that new data is available
- return parent->GetServerSession().HandleSyncRequest(thread, memory, core_timing);
+Result KClientSession::SendSyncRequest() {
+ // Create a session request.
+ KSessionRequest* request = KSessionRequest::Create(kernel);
+ R_UNLESS(request != nullptr, ResultOutOfResource);
+ SCOPE_EXIT({ request->Close(); });
+
+ // Initialize the request.
+ request->Initialize(nullptr, GetCurrentThread(kernel).GetTLSAddress(), MessageBufferSize);
+
+ // Send the request.
+ return parent->GetServerSession().OnRequest(request);
}
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_client_session.h b/src/core/hle/kernel/k_client_session.h
index 0c750d756..b4a19c546 100644
--- a/src/core/hle/kernel/k_client_session.h
+++ b/src/core/hle/kernel/k_client_session.h
@@ -46,8 +46,7 @@ public:
return parent;
}
- Result SendSyncRequest(KThread* thread, Core::Memory::Memory& memory,
- Core::Timing::CoreTiming& core_timing);
+ Result SendSyncRequest();
void OnServerClosed();
diff --git a/src/core/hle/kernel/k_code_memory.cpp b/src/core/hle/kernel/k_code_memory.cpp
index da57ceb21..4b1c134d4 100644
--- a/src/core/hle/kernel/k_code_memory.cpp
+++ b/src/core/hle/kernel/k_code_memory.cpp
@@ -34,7 +34,7 @@ Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, si
// Clear the memory.
for (const auto& block : m_page_group.Nodes()) {
- std::memset(device_memory.GetPointer(block.GetAddress()), 0xFF, block.GetSize());
+ std::memset(device_memory.GetPointer<void>(block.GetAddress()), 0xFF, block.GetSize());
}
// Set remaining tracking members.
diff --git a/src/core/hle/kernel/k_dynamic_page_manager.h b/src/core/hle/kernel/k_dynamic_page_manager.h
new file mode 100644
index 000000000..9076c8fa3
--- /dev/null
+++ b/src/core/hle/kernel/k_dynamic_page_manager.h
@@ -0,0 +1,136 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "common/alignment.h"
+#include "common/common_types.h"
+#include "core/hle/kernel/k_page_bitmap.h"
+#include "core/hle/kernel/k_spin_lock.h"
+#include "core/hle/kernel/memory_types.h"
+#include "core/hle/kernel/svc_results.h"
+
+namespace Kernel {
+
+class KDynamicPageManager {
+public:
+ class PageBuffer {
+ private:
+ u8 m_buffer[PageSize];
+ };
+ static_assert(sizeof(PageBuffer) == PageSize);
+
+public:
+ KDynamicPageManager() = default;
+
+ template <typename T>
+ T* GetPointer(VAddr addr) {
+ return reinterpret_cast<T*>(m_backing_memory.data() + (addr - m_address));
+ }
+
+ template <typename T>
+ const T* GetPointer(VAddr addr) const {
+ return reinterpret_cast<T*>(m_backing_memory.data() + (addr - m_address));
+ }
+
+ Result Initialize(VAddr addr, size_t sz) {
+ // We need to have positive size.
+ R_UNLESS(sz > 0, ResultOutOfMemory);
+ m_backing_memory.resize(sz);
+
+ // Calculate management overhead.
+ const size_t management_size =
+ KPageBitmap::CalculateManagementOverheadSize(sz / sizeof(PageBuffer));
+ const size_t allocatable_size = sz - management_size;
+
+ // Set tracking fields.
+ m_address = addr;
+ m_size = Common::AlignDown(allocatable_size, sizeof(PageBuffer));
+ m_count = allocatable_size / sizeof(PageBuffer);
+ R_UNLESS(m_count > 0, ResultOutOfMemory);
+
+ // Clear the management region.
+ u64* management_ptr = GetPointer<u64>(m_address + allocatable_size);
+ std::memset(management_ptr, 0, management_size);
+
+ // Initialize the bitmap.
+ m_page_bitmap.Initialize(management_ptr, m_count);
+
+ // Free the pages to the bitmap.
+ for (size_t i = 0; i < m_count; i++) {
+ // Ensure the freed page is all-zero.
+ std::memset(GetPointer<PageBuffer>(m_address) + i, 0, PageSize);
+
+ // Set the bit for the free page.
+ m_page_bitmap.SetBit(i);
+ }
+
+ R_SUCCEED();
+ }
+
+ VAddr GetAddress() const {
+ return m_address;
+ }
+ size_t GetSize() const {
+ return m_size;
+ }
+ size_t GetUsed() const {
+ return m_used;
+ }
+ size_t GetPeak() const {
+ return m_peak;
+ }
+ size_t GetCount() const {
+ return m_count;
+ }
+
+ PageBuffer* Allocate() {
+ // Take the lock.
+ // TODO(bunnei): We should disable interrupts here via KScopedInterruptDisable.
+ KScopedSpinLock lk(m_lock);
+
+ // Find a random free block.
+ s64 soffset = m_page_bitmap.FindFreeBlock(true);
+ if (soffset < 0) [[unlikely]] {
+ return nullptr;
+ }
+
+ const size_t offset = static_cast<size_t>(soffset);
+
+ // Update our tracking.
+ m_page_bitmap.ClearBit(offset);
+ m_peak = std::max(m_peak, (++m_used));
+
+ return GetPointer<PageBuffer>(m_address) + offset;
+ }
+
+ void Free(PageBuffer* pb) {
+ // Ensure all pages in the heap are zero.
+ std::memset(pb, 0, PageSize);
+
+ // Take the lock.
+ // TODO(bunnei): We should disable interrupts here via KScopedInterruptDisable.
+ KScopedSpinLock lk(m_lock);
+
+ // Set the bit for the free page.
+ size_t offset = (reinterpret_cast<uintptr_t>(pb) - m_address) / sizeof(PageBuffer);
+ m_page_bitmap.SetBit(offset);
+
+ // Decrement our used count.
+ --m_used;
+ }
+
+private:
+ KSpinLock m_lock;
+ KPageBitmap m_page_bitmap;
+ size_t m_used{};
+ size_t m_peak{};
+ size_t m_count{};
+ VAddr m_address{};
+ size_t m_size{};
+
+ // TODO(bunnei): Back by host memory until we emulate kernel virtual address space.
+ std::vector<u8> m_backing_memory;
+};
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/k_dynamic_resource_manager.h b/src/core/hle/kernel/k_dynamic_resource_manager.h
new file mode 100644
index 000000000..1ce517e8e
--- /dev/null
+++ b/src/core/hle/kernel/k_dynamic_resource_manager.h
@@ -0,0 +1,58 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "common/common_funcs.h"
+#include "core/hle/kernel/k_dynamic_slab_heap.h"
+#include "core/hle/kernel/k_memory_block.h"
+
+namespace Kernel {
+
+template <typename T, bool ClearNode = false>
+class KDynamicResourceManager {
+ YUZU_NON_COPYABLE(KDynamicResourceManager);
+ YUZU_NON_MOVEABLE(KDynamicResourceManager);
+
+public:
+ using DynamicSlabType = KDynamicSlabHeap<T, ClearNode>;
+
+public:
+ constexpr KDynamicResourceManager() = default;
+
+ constexpr size_t GetSize() const {
+ return m_slab_heap->GetSize();
+ }
+ constexpr size_t GetUsed() const {
+ return m_slab_heap->GetUsed();
+ }
+ constexpr size_t GetPeak() const {
+ return m_slab_heap->GetPeak();
+ }
+ constexpr size_t GetCount() const {
+ return m_slab_heap->GetCount();
+ }
+
+ void Initialize(KDynamicPageManager* page_allocator, DynamicSlabType* slab_heap) {
+ m_page_allocator = page_allocator;
+ m_slab_heap = slab_heap;
+ }
+
+ T* Allocate() const {
+ return m_slab_heap->Allocate(m_page_allocator);
+ }
+
+ void Free(T* t) const {
+ m_slab_heap->Free(t);
+ }
+
+private:
+ KDynamicPageManager* m_page_allocator{};
+ DynamicSlabType* m_slab_heap{};
+};
+
+class KMemoryBlockSlabManager : public KDynamicResourceManager<KMemoryBlock> {};
+
+using KMemoryBlockSlabHeap = typename KMemoryBlockSlabManager::DynamicSlabType;
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/k_dynamic_slab_heap.h b/src/core/hle/kernel/k_dynamic_slab_heap.h
new file mode 100644
index 000000000..3a0ddd050
--- /dev/null
+++ b/src/core/hle/kernel/k_dynamic_slab_heap.h
@@ -0,0 +1,122 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <atomic>
+
+#include "common/common_funcs.h"
+#include "core/hle/kernel/k_dynamic_page_manager.h"
+#include "core/hle/kernel/k_slab_heap.h"
+
+namespace Kernel {
+
+template <typename T, bool ClearNode = false>
+class KDynamicSlabHeap : protected impl::KSlabHeapImpl {
+ YUZU_NON_COPYABLE(KDynamicSlabHeap);
+ YUZU_NON_MOVEABLE(KDynamicSlabHeap);
+
+public:
+ constexpr KDynamicSlabHeap() = default;
+
+ constexpr VAddr GetAddress() const {
+ return m_address;
+ }
+ constexpr size_t GetSize() const {
+ return m_size;
+ }
+ constexpr size_t GetUsed() const {
+ return m_used.load();
+ }
+ constexpr size_t GetPeak() const {
+ return m_peak.load();
+ }
+ constexpr size_t GetCount() const {
+ return m_count.load();
+ }
+
+ constexpr bool IsInRange(VAddr addr) const {
+ return this->GetAddress() <= addr && addr <= this->GetAddress() + this->GetSize() - 1;
+ }
+
+ void Initialize(KDynamicPageManager* page_allocator, size_t num_objects) {
+ ASSERT(page_allocator != nullptr);
+
+ // Initialize members.
+ m_address = page_allocator->GetAddress();
+ m_size = page_allocator->GetSize();
+
+ // Initialize the base allocator.
+ KSlabHeapImpl::Initialize();
+
+ // Allocate until we have the correct number of objects.
+ while (m_count.load() < num_objects) {
+ auto* allocated = reinterpret_cast<T*>(page_allocator->Allocate());
+ ASSERT(allocated != nullptr);
+
+ for (size_t i = 0; i < sizeof(PageBuffer) / sizeof(T); i++) {
+ KSlabHeapImpl::Free(allocated + i);
+ }
+
+ m_count += sizeof(PageBuffer) / sizeof(T);
+ }
+ }
+
+ T* Allocate(KDynamicPageManager* page_allocator) {
+ T* allocated = static_cast<T*>(KSlabHeapImpl::Allocate());
+
+ // If we successfully allocated and we should clear the node, do so.
+ if constexpr (ClearNode) {
+ if (allocated != nullptr) [[likely]] {
+ reinterpret_cast<KSlabHeapImpl::Node*>(allocated)->next = nullptr;
+ }
+ }
+
+ // If we fail to allocate, try to get a new page from our next allocator.
+ if (allocated == nullptr) [[unlikely]] {
+ if (page_allocator != nullptr) {
+ allocated = reinterpret_cast<T*>(page_allocator->Allocate());
+ if (allocated != nullptr) {
+ // If we succeeded in getting a page, free the rest to our slab.
+ for (size_t i = 1; i < sizeof(PageBuffer) / sizeof(T); i++) {
+ KSlabHeapImpl::Free(allocated + i);
+ }
+ m_count += sizeof(PageBuffer) / sizeof(T);
+ }
+ }
+ }
+
+ if (allocated != nullptr) [[likely]] {
+ // Construct the object.
+ std::construct_at(allocated);
+
+ // Update our tracking.
+ const size_t used = ++m_used;
+ size_t peak = m_peak.load();
+ while (peak < used) {
+ if (m_peak.compare_exchange_weak(peak, used, std::memory_order_relaxed)) {
+ break;
+ }
+ }
+ }
+
+ return allocated;
+ }
+
+ void Free(T* t) {
+ KSlabHeapImpl::Free(t);
+ --m_used;
+ }
+
+private:
+ using PageBuffer = KDynamicPageManager::PageBuffer;
+
+private:
+ std::atomic<size_t> m_used{};
+ std::atomic<size_t> m_peak{};
+ std::atomic<size_t> m_count{};
+ VAddr m_address{};
+ size_t m_size{};
+};
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/k_event.cpp b/src/core/hle/kernel/k_event.cpp
index e52fafbc7..78ca59463 100644
--- a/src/core/hle/kernel/k_event.cpp
+++ b/src/core/hle/kernel/k_event.cpp
@@ -8,39 +8,45 @@
namespace Kernel {
KEvent::KEvent(KernelCore& kernel_)
- : KAutoObjectWithSlabHeapAndContainer{kernel_}, readable_event{kernel_}, writable_event{
- kernel_} {}
+ : KAutoObjectWithSlabHeapAndContainer{kernel_}, m_readable_event{kernel_} {}
KEvent::~KEvent() = default;
-void KEvent::Initialize(std::string&& name_, KProcess* owner_) {
- // Increment reference count.
- // Because reference count is one on creation, this will result
- // in a reference count of two. Thus, when both readable and
- // writable events are closed this object will be destroyed.
- Open();
+void KEvent::Initialize(KProcess* owner) {
+ // Create our readable event.
+ KAutoObject::Create(std::addressof(m_readable_event));
- // Create our sub events.
- KAutoObject::Create(std::addressof(readable_event));
- KAutoObject::Create(std::addressof(writable_event));
-
- // Initialize our sub sessions.
- readable_event.Initialize(this, name_ + ":Readable");
- writable_event.Initialize(this, name_ + ":Writable");
+ // Initialize our readable event.
+ m_readable_event.Initialize(this);
// Set our owner process.
- owner = owner_;
- owner->Open();
+ m_owner = owner;
+ m_owner->Open();
// Mark initialized.
- name = std::move(name_);
- initialized = true;
+ m_initialized = true;
}
void KEvent::Finalize() {
KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList>::Finalize();
}
+Result KEvent::Signal() {
+ KScopedSchedulerLock sl{kernel};
+
+ R_SUCCEED_IF(m_readable_event_destroyed);
+
+ return m_readable_event.Signal();
+}
+
+Result KEvent::Clear() {
+ KScopedSchedulerLock sl{kernel};
+
+ R_SUCCEED_IF(m_readable_event_destroyed);
+
+ return m_readable_event.Clear();
+}
+
void KEvent::PostDestroy(uintptr_t arg) {
// Release the event count resource the owner process holds.
KProcess* owner = reinterpret_cast<KProcess*>(arg);
diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h
index 2ff828feb..48ce7d9a0 100644
--- a/src/core/hle/kernel/k_event.h
+++ b/src/core/hle/kernel/k_event.h
@@ -4,14 +4,12 @@
#pragma once
#include "core/hle/kernel/k_readable_event.h"
-#include "core/hle/kernel/k_writable_event.h"
#include "core/hle/kernel/slab_helpers.h"
namespace Kernel {
class KernelCore;
class KReadableEvent;
-class KWritableEvent;
class KProcess;
class KEvent final : public KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList> {
@@ -21,37 +19,40 @@ public:
explicit KEvent(KernelCore& kernel_);
~KEvent() override;
- void Initialize(std::string&& name, KProcess* owner_);
+ void Initialize(KProcess* owner);
void Finalize() override;
bool IsInitialized() const override {
- return initialized;
+ return m_initialized;
}
uintptr_t GetPostDestroyArgument() const override {
- return reinterpret_cast<uintptr_t>(owner);
+ return reinterpret_cast<uintptr_t>(m_owner);
}
KProcess* GetOwner() const override {
- return owner;
+ return m_owner;
}
KReadableEvent& GetReadableEvent() {
- return readable_event;
- }
-
- KWritableEvent& GetWritableEvent() {
- return writable_event;
+ return m_readable_event;
}
static void PostDestroy(uintptr_t arg);
+ Result Signal();
+ Result Clear();
+
+ void OnReadableEventDestroyed() {
+ m_readable_event_destroyed = true;
+ }
+
private:
- KReadableEvent readable_event;
- KWritableEvent writable_event;
- KProcess* owner{};
- bool initialized{};
+ KReadableEvent m_readable_event;
+ KProcess* m_owner{};
+ bool m_initialized{};
+ bool m_readable_event_destroyed{};
};
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_interrupt_manager.cpp b/src/core/hle/kernel/k_interrupt_manager.cpp
index 1b577a5b3..4a6b60d26 100644
--- a/src/core/hle/kernel/k_interrupt_manager.cpp
+++ b/src/core/hle/kernel/k_interrupt_manager.cpp
@@ -11,29 +11,34 @@
namespace Kernel::KInterruptManager {
void HandleInterrupt(KernelCore& kernel, s32 core_id) {
- auto* process = kernel.CurrentProcess();
- if (!process) {
- return;
- }
-
// Acknowledge the interrupt.
kernel.PhysicalCore(core_id).ClearInterrupt();
auto& current_thread = GetCurrentThread(kernel);
- // If the user disable count is set, we may need to pin the current thread.
- if (current_thread.GetUserDisableCount() && !process->GetPinnedThread(core_id)) {
- KScopedSchedulerLock sl{kernel};
+ if (auto* process = kernel.CurrentProcess(); process) {
+ // If the user disable count is set, we may need to pin the current thread.
+ if (current_thread.GetUserDisableCount() && !process->GetPinnedThread(core_id)) {
+ KScopedSchedulerLock sl{kernel};
- // Pin the current thread.
- process->PinCurrentThread(core_id);
+ // Pin the current thread.
+ process->PinCurrentThread(core_id);
- // Set the interrupt flag for the thread.
- GetCurrentThread(kernel).SetInterruptFlag();
+ // Set the interrupt flag for the thread.
+ GetCurrentThread(kernel).SetInterruptFlag();
+ }
}
// Request interrupt scheduling.
kernel.CurrentScheduler()->RequestScheduleOnInterrupt();
}
+void SendInterProcessorInterrupt(KernelCore& kernel, u64 core_mask) {
+ for (std::size_t core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; ++core_id) {
+ if (core_mask & (1ULL << core_id)) {
+ kernel.PhysicalCore(core_id).Interrupt();
+ }
+ }
+}
+
} // namespace Kernel::KInterruptManager
diff --git a/src/core/hle/kernel/k_interrupt_manager.h b/src/core/hle/kernel/k_interrupt_manager.h
index f103dfe3f..803dc9211 100644
--- a/src/core/hle/kernel/k_interrupt_manager.h
+++ b/src/core/hle/kernel/k_interrupt_manager.h
@@ -11,6 +11,8 @@ class KernelCore;
namespace KInterruptManager {
void HandleInterrupt(KernelCore& kernel, s32 core_id);
-}
+void SendInterProcessorInterrupt(KernelCore& kernel, u64 core_mask);
+
+} // namespace KInterruptManager
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_linked_list.h b/src/core/hle/kernel/k_linked_list.h
index 78859ced3..29ebd16b7 100644
--- a/src/core/hle/kernel/k_linked_list.h
+++ b/src/core/hle/kernel/k_linked_list.h
@@ -16,6 +16,7 @@ class KLinkedListNode : public boost::intrusive::list_base_hook<>,
public KSlabAllocated<KLinkedListNode> {
public:
+ explicit KLinkedListNode(KernelCore&) {}
KLinkedListNode() = default;
void Initialize(void* it) {
diff --git a/src/core/hle/kernel/k_memory_block.h b/src/core/hle/kernel/k_memory_block.h
index 18df1f836..9444f6bd2 100644
--- a/src/core/hle/kernel/k_memory_block.h
+++ b/src/core/hle/kernel/k_memory_block.h
@@ -6,6 +6,7 @@
#include "common/alignment.h"
#include "common/assert.h"
#include "common/common_types.h"
+#include "common/intrusive_red_black_tree.h"
#include "core/hle/kernel/memory_types.h"
#include "core/hle/kernel/svc_types.h"
@@ -168,9 +169,8 @@ constexpr KMemoryPermission ConvertToKMemoryPermission(Svc::MemoryPermission per
enum class KMemoryAttribute : u8 {
None = 0x00,
- Mask = 0x7F,
- All = Mask,
- DontCareMask = 0x80,
+ All = 0xFF,
+ UserMask = All,
Locked = static_cast<u8>(Svc::MemoryAttribute::Locked),
IpcLocked = static_cast<u8>(Svc::MemoryAttribute::IpcLocked),
@@ -178,76 +178,112 @@ enum class KMemoryAttribute : u8 {
Uncached = static_cast<u8>(Svc::MemoryAttribute::Uncached),
SetMask = Uncached,
-
- IpcAndDeviceMapped = IpcLocked | DeviceShared,
- LockedAndIpcLocked = Locked | IpcLocked,
- DeviceSharedAndUncached = DeviceShared | Uncached
};
DECLARE_ENUM_FLAG_OPERATORS(KMemoryAttribute);
-static_assert((static_cast<u8>(KMemoryAttribute::Mask) &
- static_cast<u8>(KMemoryAttribute::DontCareMask)) == 0);
+enum class KMemoryBlockDisableMergeAttribute : u8 {
+ None = 0,
+ Normal = (1u << 0),
+ DeviceLeft = (1u << 1),
+ IpcLeft = (1u << 2),
+ Locked = (1u << 3),
+ DeviceRight = (1u << 4),
+
+ AllLeft = Normal | DeviceLeft | IpcLeft | Locked,
+ AllRight = DeviceRight,
+};
+DECLARE_ENUM_FLAG_OPERATORS(KMemoryBlockDisableMergeAttribute);
struct KMemoryInfo {
- VAddr addr{};
- std::size_t size{};
- KMemoryState state{};
- KMemoryPermission perm{};
- KMemoryAttribute attribute{};
- KMemoryPermission original_perm{};
- u16 ipc_lock_count{};
- u16 device_use_count{};
+ uintptr_t m_address;
+ size_t m_size;
+ KMemoryState m_state;
+ u16 m_device_disable_merge_left_count;
+ u16 m_device_disable_merge_right_count;
+ u16 m_ipc_lock_count;
+ u16 m_device_use_count;
+ u16 m_ipc_disable_merge_count;
+ KMemoryPermission m_permission;
+ KMemoryAttribute m_attribute;
+ KMemoryPermission m_original_permission;
+ KMemoryBlockDisableMergeAttribute m_disable_merge_attribute;
constexpr Svc::MemoryInfo GetSvcMemoryInfo() const {
return {
- addr,
- size,
- static_cast<Svc::MemoryState>(state & KMemoryState::Mask),
- static_cast<Svc::MemoryAttribute>(attribute & KMemoryAttribute::Mask),
- static_cast<Svc::MemoryPermission>(perm & KMemoryPermission::UserMask),
- ipc_lock_count,
- device_use_count,
+ .addr = m_address,
+ .size = m_size,
+ .state = static_cast<Svc::MemoryState>(m_state & KMemoryState::Mask),
+ .attr = static_cast<Svc::MemoryAttribute>(m_attribute & KMemoryAttribute::UserMask),
+ .perm = static_cast<Svc::MemoryPermission>(m_permission & KMemoryPermission::UserMask),
+ .ipc_refcount = m_ipc_lock_count,
+ .device_refcount = m_device_use_count,
+ .padding = {},
};
}
- constexpr VAddr GetAddress() const {
- return addr;
+ constexpr uintptr_t GetAddress() const {
+ return m_address;
+ }
+
+ constexpr size_t GetSize() const {
+ return m_size;
}
- constexpr std::size_t GetSize() const {
- return size;
+
+ constexpr size_t GetNumPages() const {
+ return this->GetSize() / PageSize;
}
- constexpr std::size_t GetNumPages() const {
- return GetSize() / PageSize;
+
+ constexpr uintptr_t GetEndAddress() const {
+ return this->GetAddress() + this->GetSize();
}
- constexpr VAddr GetEndAddress() const {
- return GetAddress() + GetSize();
+
+ constexpr uintptr_t GetLastAddress() const {
+ return this->GetEndAddress() - 1;
}
- constexpr VAddr GetLastAddress() const {
- return GetEndAddress() - 1;
+
+ constexpr u16 GetIpcLockCount() const {
+ return m_ipc_lock_count;
}
+
+ constexpr u16 GetIpcDisableMergeCount() const {
+ return m_ipc_disable_merge_count;
+ }
+
constexpr KMemoryState GetState() const {
- return state;
+ return m_state;
+ }
+
+ constexpr KMemoryPermission GetPermission() const {
+ return m_permission;
}
+
+ constexpr KMemoryPermission GetOriginalPermission() const {
+ return m_original_permission;
+ }
+
constexpr KMemoryAttribute GetAttribute() const {
- return attribute;
+ return m_attribute;
}
- constexpr KMemoryPermission GetPermission() const {
- return perm;
+
+ constexpr KMemoryBlockDisableMergeAttribute GetDisableMergeAttribute() const {
+ return m_disable_merge_attribute;
}
};
-class KMemoryBlock final {
- friend class KMemoryBlockManager;
-
+class KMemoryBlock : public Common::IntrusiveRedBlackTreeBaseNode<KMemoryBlock> {
private:
- VAddr addr{};
- std::size_t num_pages{};
- KMemoryState state{KMemoryState::None};
- u16 ipc_lock_count{};
- u16 device_use_count{};
- KMemoryPermission perm{KMemoryPermission::None};
- KMemoryPermission original_perm{KMemoryPermission::None};
- KMemoryAttribute attribute{KMemoryAttribute::None};
+ u16 m_device_disable_merge_left_count;
+ u16 m_device_disable_merge_right_count;
+ VAddr m_address;
+ size_t m_num_pages;
+ KMemoryState m_memory_state;
+ u16 m_ipc_lock_count;
+ u16 m_device_use_count;
+ u16 m_ipc_disable_merge_count;
+ KMemoryPermission m_permission;
+ KMemoryPermission m_original_permission;
+ KMemoryAttribute m_attribute;
+ KMemoryBlockDisableMergeAttribute m_disable_merge_attribute;
public:
static constexpr int Compare(const KMemoryBlock& lhs, const KMemoryBlock& rhs) {
@@ -261,113 +297,349 @@ public:
}
public:
- constexpr KMemoryBlock() = default;
- constexpr KMemoryBlock(VAddr addr_, std::size_t num_pages_, KMemoryState state_,
- KMemoryPermission perm_, KMemoryAttribute attribute_)
- : addr{addr_}, num_pages(num_pages_), state{state_}, perm{perm_}, attribute{attribute_} {}
-
constexpr VAddr GetAddress() const {
- return addr;
+ return m_address;
}
- constexpr std::size_t GetNumPages() const {
- return num_pages;
+ constexpr size_t GetNumPages() const {
+ return m_num_pages;
}
- constexpr std::size_t GetSize() const {
- return GetNumPages() * PageSize;
+ constexpr size_t GetSize() const {
+ return this->GetNumPages() * PageSize;
}
constexpr VAddr GetEndAddress() const {
- return GetAddress() + GetSize();
+ return this->GetAddress() + this->GetSize();
}
constexpr VAddr GetLastAddress() const {
- return GetEndAddress() - 1;
+ return this->GetEndAddress() - 1;
+ }
+
+ constexpr u16 GetIpcLockCount() const {
+ return m_ipc_lock_count;
+ }
+
+ constexpr u16 GetIpcDisableMergeCount() const {
+ return m_ipc_disable_merge_count;
+ }
+
+ constexpr KMemoryPermission GetPermission() const {
+ return m_permission;
+ }
+
+ constexpr KMemoryPermission GetOriginalPermission() const {
+ return m_original_permission;
+ }
+
+ constexpr KMemoryAttribute GetAttribute() const {
+ return m_attribute;
}
constexpr KMemoryInfo GetMemoryInfo() const {
return {
- GetAddress(), GetSize(), state, perm,
- attribute, original_perm, ipc_lock_count, device_use_count,
+ .m_address = this->GetAddress(),
+ .m_size = this->GetSize(),
+ .m_state = m_memory_state,
+ .m_device_disable_merge_left_count = m_device_disable_merge_left_count,
+ .m_device_disable_merge_right_count = m_device_disable_merge_right_count,
+ .m_ipc_lock_count = m_ipc_lock_count,
+ .m_device_use_count = m_device_use_count,
+ .m_ipc_disable_merge_count = m_ipc_disable_merge_count,
+ .m_permission = m_permission,
+ .m_attribute = m_attribute,
+ .m_original_permission = m_original_permission,
+ .m_disable_merge_attribute = m_disable_merge_attribute,
};
}
- void ShareToDevice(KMemoryPermission /*new_perm*/) {
- ASSERT((attribute & KMemoryAttribute::DeviceShared) == KMemoryAttribute::DeviceShared ||
- device_use_count == 0);
- attribute |= KMemoryAttribute::DeviceShared;
- const u16 new_use_count{++device_use_count};
- ASSERT(new_use_count > 0);
+public:
+ explicit KMemoryBlock() = default;
+
+ constexpr KMemoryBlock(VAddr addr, size_t np, KMemoryState ms, KMemoryPermission p,
+ KMemoryAttribute attr)
+ : Common::IntrusiveRedBlackTreeBaseNode<KMemoryBlock>(),
+ m_device_disable_merge_left_count(), m_device_disable_merge_right_count(),
+ m_address(addr), m_num_pages(np), m_memory_state(ms), m_ipc_lock_count(0),
+ m_device_use_count(0), m_ipc_disable_merge_count(), m_permission(p),
+ m_original_permission(KMemoryPermission::None), m_attribute(attr),
+ m_disable_merge_attribute() {}
+
+ constexpr void Initialize(VAddr addr, size_t np, KMemoryState ms, KMemoryPermission p,
+ KMemoryAttribute attr) {
+ m_device_disable_merge_left_count = 0;
+ m_device_disable_merge_right_count = 0;
+ m_address = addr;
+ m_num_pages = np;
+ m_memory_state = ms;
+ m_ipc_lock_count = 0;
+ m_device_use_count = 0;
+ m_permission = p;
+ m_original_permission = KMemoryPermission::None;
+ m_attribute = attr;
+ m_disable_merge_attribute = KMemoryBlockDisableMergeAttribute::None;
+ }
+
+ constexpr bool HasProperties(KMemoryState s, KMemoryPermission p, KMemoryAttribute a) const {
+ constexpr auto AttributeIgnoreMask =
+ KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared;
+ return m_memory_state == s && m_permission == p &&
+ (m_attribute | AttributeIgnoreMask) == (a | AttributeIgnoreMask);
+ }
+
+ constexpr bool HasSameProperties(const KMemoryBlock& rhs) const {
+ return m_memory_state == rhs.m_memory_state && m_permission == rhs.m_permission &&
+ m_original_permission == rhs.m_original_permission &&
+ m_attribute == rhs.m_attribute && m_ipc_lock_count == rhs.m_ipc_lock_count &&
+ m_device_use_count == rhs.m_device_use_count;
+ }
+
+ constexpr bool CanMergeWith(const KMemoryBlock& rhs) const {
+ return this->HasSameProperties(rhs) &&
+ (m_disable_merge_attribute & KMemoryBlockDisableMergeAttribute::AllRight) ==
+ KMemoryBlockDisableMergeAttribute::None &&
+ (rhs.m_disable_merge_attribute & KMemoryBlockDisableMergeAttribute::AllLeft) ==
+ KMemoryBlockDisableMergeAttribute::None;
}
- void UnshareToDevice(KMemoryPermission /*new_perm*/) {
- ASSERT((attribute & KMemoryAttribute::DeviceShared) == KMemoryAttribute::DeviceShared);
- const u16 prev_use_count{device_use_count--};
- ASSERT(prev_use_count > 0);
- if (prev_use_count == 1) {
- attribute &= ~KMemoryAttribute::DeviceShared;
+ constexpr bool Contains(VAddr addr) const {
+ return this->GetAddress() <= addr && addr <= this->GetEndAddress();
+ }
+
+ constexpr void Add(const KMemoryBlock& added_block) {
+ ASSERT(added_block.GetNumPages() > 0);
+ ASSERT(this->GetAddress() + added_block.GetSize() - 1 <
+ this->GetEndAddress() + added_block.GetSize() - 1);
+
+ m_num_pages += added_block.GetNumPages();
+ m_disable_merge_attribute = static_cast<KMemoryBlockDisableMergeAttribute>(
+ m_disable_merge_attribute | added_block.m_disable_merge_attribute);
+ m_device_disable_merge_right_count = added_block.m_device_disable_merge_right_count;
+ }
+
+ constexpr void Update(KMemoryState s, KMemoryPermission p, KMemoryAttribute a,
+ bool set_disable_merge_attr, u8 set_mask, u8 clear_mask) {
+ ASSERT(m_original_permission == KMemoryPermission::None);
+ ASSERT((m_attribute & KMemoryAttribute::IpcLocked) == KMemoryAttribute::None);
+
+ m_memory_state = s;
+ m_permission = p;
+ m_attribute = static_cast<KMemoryAttribute>(
+ a | (m_attribute & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)));
+
+ if (set_disable_merge_attr && set_mask != 0) {
+ m_disable_merge_attribute = m_disable_merge_attribute |
+ static_cast<KMemoryBlockDisableMergeAttribute>(set_mask);
+ }
+ if (clear_mask != 0) {
+ m_disable_merge_attribute = m_disable_merge_attribute &
+ static_cast<KMemoryBlockDisableMergeAttribute>(~clear_mask);
}
}
-private:
- constexpr bool HasProperties(KMemoryState s, KMemoryPermission p, KMemoryAttribute a) const {
- constexpr KMemoryAttribute AttributeIgnoreMask{KMemoryAttribute::DontCareMask |
- KMemoryAttribute::IpcLocked |
- KMemoryAttribute::DeviceShared};
- return state == s && perm == p &&
- (attribute | AttributeIgnoreMask) == (a | AttributeIgnoreMask);
+ constexpr void Split(KMemoryBlock* block, VAddr addr) {
+ ASSERT(this->GetAddress() < addr);
+ ASSERT(this->Contains(addr));
+ ASSERT(Common::IsAligned(addr, PageSize));
+
+ block->m_address = m_address;
+ block->m_num_pages = (addr - this->GetAddress()) / PageSize;
+ block->m_memory_state = m_memory_state;
+ block->m_ipc_lock_count = m_ipc_lock_count;
+ block->m_device_use_count = m_device_use_count;
+ block->m_permission = m_permission;
+ block->m_original_permission = m_original_permission;
+ block->m_attribute = m_attribute;
+ block->m_disable_merge_attribute = static_cast<KMemoryBlockDisableMergeAttribute>(
+ m_disable_merge_attribute & KMemoryBlockDisableMergeAttribute::AllLeft);
+ block->m_ipc_disable_merge_count = m_ipc_disable_merge_count;
+ block->m_device_disable_merge_left_count = m_device_disable_merge_left_count;
+ block->m_device_disable_merge_right_count = 0;
+
+ m_address = addr;
+ m_num_pages -= block->m_num_pages;
+
+ m_ipc_disable_merge_count = 0;
+ m_device_disable_merge_left_count = 0;
+ m_disable_merge_attribute = static_cast<KMemoryBlockDisableMergeAttribute>(
+ m_disable_merge_attribute & KMemoryBlockDisableMergeAttribute::AllRight);
}
- constexpr bool HasSameProperties(const KMemoryBlock& rhs) const {
- return state == rhs.state && perm == rhs.perm && original_perm == rhs.original_perm &&
- attribute == rhs.attribute && ipc_lock_count == rhs.ipc_lock_count &&
- device_use_count == rhs.device_use_count;
+ constexpr void UpdateDeviceDisableMergeStateForShareLeft(
+ [[maybe_unused]] KMemoryPermission new_perm, bool left, [[maybe_unused]] bool right) {
+ if (left) {
+ m_disable_merge_attribute = static_cast<KMemoryBlockDisableMergeAttribute>(
+ m_disable_merge_attribute | KMemoryBlockDisableMergeAttribute::DeviceLeft);
+ const u16 new_device_disable_merge_left_count = ++m_device_disable_merge_left_count;
+ ASSERT(new_device_disable_merge_left_count > 0);
+ }
}
- constexpr bool Contains(VAddr start) const {
- return GetAddress() <= start && start <= GetEndAddress();
+ constexpr void UpdateDeviceDisableMergeStateForShareRight(
+ [[maybe_unused]] KMemoryPermission new_perm, [[maybe_unused]] bool left, bool right) {
+ if (right) {
+ m_disable_merge_attribute = static_cast<KMemoryBlockDisableMergeAttribute>(
+ m_disable_merge_attribute | KMemoryBlockDisableMergeAttribute::DeviceRight);
+ const u16 new_device_disable_merge_right_count = ++m_device_disable_merge_right_count;
+ ASSERT(new_device_disable_merge_right_count > 0);
+ }
+ }
+
+ constexpr void UpdateDeviceDisableMergeStateForShare(KMemoryPermission new_perm, bool left,
+ bool right) {
+ this->UpdateDeviceDisableMergeStateForShareLeft(new_perm, left, right);
+ this->UpdateDeviceDisableMergeStateForShareRight(new_perm, left, right);
}
- constexpr void Add(std::size_t count) {
- ASSERT(count > 0);
- ASSERT(GetAddress() + count * PageSize - 1 < GetEndAddress() + count * PageSize - 1);
+ constexpr void ShareToDevice([[maybe_unused]] KMemoryPermission new_perm, bool left,
+ bool right) {
+ // We must either be shared or have a zero lock count.
+ ASSERT((m_attribute & KMemoryAttribute::DeviceShared) == KMemoryAttribute::DeviceShared ||
+ m_device_use_count == 0);
- num_pages += count;
+ // Share.
+ const u16 new_count = ++m_device_use_count;
+ ASSERT(new_count > 0);
+
+ m_attribute = static_cast<KMemoryAttribute>(m_attribute | KMemoryAttribute::DeviceShared);
+
+ this->UpdateDeviceDisableMergeStateForShare(new_perm, left, right);
}
- constexpr void Update(KMemoryState new_state, KMemoryPermission new_perm,
- KMemoryAttribute new_attribute) {
- ASSERT(original_perm == KMemoryPermission::None);
- ASSERT((attribute & KMemoryAttribute::IpcLocked) == KMemoryAttribute::None);
+ constexpr void UpdateDeviceDisableMergeStateForUnshareLeft(
+ [[maybe_unused]] KMemoryPermission new_perm, bool left, [[maybe_unused]] bool right) {
- state = new_state;
- perm = new_perm;
+ if (left) {
+ if (!m_device_disable_merge_left_count) {
+ return;
+ }
+ --m_device_disable_merge_left_count;
+ }
- attribute = static_cast<KMemoryAttribute>(
- new_attribute |
- (attribute & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)));
+ m_device_disable_merge_left_count =
+ std::min(m_device_disable_merge_left_count, m_device_use_count);
+
+ if (m_device_disable_merge_left_count == 0) {
+ m_disable_merge_attribute = static_cast<KMemoryBlockDisableMergeAttribute>(
+ m_disable_merge_attribute & ~KMemoryBlockDisableMergeAttribute::DeviceLeft);
+ }
}
- constexpr KMemoryBlock Split(VAddr split_addr) {
- ASSERT(GetAddress() < split_addr);
- ASSERT(Contains(split_addr));
- ASSERT(Common::IsAligned(split_addr, PageSize));
+ constexpr void UpdateDeviceDisableMergeStateForUnshareRight(
+ [[maybe_unused]] KMemoryPermission new_perm, [[maybe_unused]] bool left, bool right) {
+ if (right) {
+ const u16 old_device_disable_merge_right_count = m_device_disable_merge_right_count--;
+ ASSERT(old_device_disable_merge_right_count > 0);
+ if (old_device_disable_merge_right_count == 1) {
+ m_disable_merge_attribute = static_cast<KMemoryBlockDisableMergeAttribute>(
+ m_disable_merge_attribute & ~KMemoryBlockDisableMergeAttribute::DeviceRight);
+ }
+ }
+ }
- KMemoryBlock block;
- block.addr = addr;
- block.num_pages = (split_addr - GetAddress()) / PageSize;
- block.state = state;
- block.ipc_lock_count = ipc_lock_count;
- block.device_use_count = device_use_count;
- block.perm = perm;
- block.original_perm = original_perm;
- block.attribute = attribute;
+ constexpr void UpdateDeviceDisableMergeStateForUnshare(KMemoryPermission new_perm, bool left,
+ bool right) {
+ this->UpdateDeviceDisableMergeStateForUnshareLeft(new_perm, left, right);
+ this->UpdateDeviceDisableMergeStateForUnshareRight(new_perm, left, right);
+ }
- addr = split_addr;
- num_pages -= block.num_pages;
+ constexpr void UnshareToDevice([[maybe_unused]] KMemoryPermission new_perm, bool left,
+ bool right) {
+ // We must be shared.
+ ASSERT((m_attribute & KMemoryAttribute::DeviceShared) == KMemoryAttribute::DeviceShared);
+
+ // Unhare.
+ const u16 old_count = m_device_use_count--;
+ ASSERT(old_count > 0);
+
+ if (old_count == 1) {
+ m_attribute =
+ static_cast<KMemoryAttribute>(m_attribute & ~KMemoryAttribute::DeviceShared);
+ }
+
+ this->UpdateDeviceDisableMergeStateForUnshare(new_perm, left, right);
+ }
+
+ constexpr void UnshareToDeviceRight([[maybe_unused]] KMemoryPermission new_perm, bool left,
+ bool right) {
+
+ // We must be shared.
+ ASSERT((m_attribute & KMemoryAttribute::DeviceShared) == KMemoryAttribute::DeviceShared);
+
+ // Unhare.
+ const u16 old_count = m_device_use_count--;
+ ASSERT(old_count > 0);
+
+ if (old_count == 1) {
+ m_attribute =
+ static_cast<KMemoryAttribute>(m_attribute & ~KMemoryAttribute::DeviceShared);
+ }
+
+ this->UpdateDeviceDisableMergeStateForUnshareRight(new_perm, left, right);
+ }
+
+ constexpr void LockForIpc(KMemoryPermission new_perm, bool left, [[maybe_unused]] bool right) {
+ // We must either be locked or have a zero lock count.
+ ASSERT((m_attribute & KMemoryAttribute::IpcLocked) == KMemoryAttribute::IpcLocked ||
+ m_ipc_lock_count == 0);
+
+ // Lock.
+ const u16 new_lock_count = ++m_ipc_lock_count;
+ ASSERT(new_lock_count > 0);
+
+ // If this is our first lock, update our permissions.
+ if (new_lock_count == 1) {
+ ASSERT(m_original_permission == KMemoryPermission::None);
+ ASSERT((m_permission | new_perm | KMemoryPermission::NotMapped) ==
+ (m_permission | KMemoryPermission::NotMapped));
+ ASSERT((m_permission & KMemoryPermission::UserExecute) !=
+ KMemoryPermission::UserExecute ||
+ (new_perm == KMemoryPermission::UserRead));
+ m_original_permission = m_permission;
+ m_permission = static_cast<KMemoryPermission>(
+ (new_perm & KMemoryPermission::IpcLockChangeMask) |
+ (m_original_permission & ~KMemoryPermission::IpcLockChangeMask));
+ }
+ m_attribute = static_cast<KMemoryAttribute>(m_attribute | KMemoryAttribute::IpcLocked);
+
+ if (left) {
+ m_disable_merge_attribute = static_cast<KMemoryBlockDisableMergeAttribute>(
+ m_disable_merge_attribute | KMemoryBlockDisableMergeAttribute::IpcLeft);
+ const u16 new_ipc_disable_merge_count = ++m_ipc_disable_merge_count;
+ ASSERT(new_ipc_disable_merge_count > 0);
+ }
+ }
+
+ constexpr void UnlockForIpc([[maybe_unused]] KMemoryPermission new_perm, bool left,
+ [[maybe_unused]] bool right) {
+ // We must be locked.
+ ASSERT((m_attribute & KMemoryAttribute::IpcLocked) == KMemoryAttribute::IpcLocked);
+
+ // Unlock.
+ const u16 old_lock_count = m_ipc_lock_count--;
+ ASSERT(old_lock_count > 0);
+
+ // If this is our last unlock, update our permissions.
+ if (old_lock_count == 1) {
+ ASSERT(m_original_permission != KMemoryPermission::None);
+ m_permission = m_original_permission;
+ m_original_permission = KMemoryPermission::None;
+ m_attribute = static_cast<KMemoryAttribute>(m_attribute & ~KMemoryAttribute::IpcLocked);
+ }
+
+ if (left) {
+ const u16 old_ipc_disable_merge_count = m_ipc_disable_merge_count--;
+ ASSERT(old_ipc_disable_merge_count > 0);
+ if (old_ipc_disable_merge_count == 1) {
+ m_disable_merge_attribute = static_cast<KMemoryBlockDisableMergeAttribute>(
+ m_disable_merge_attribute & ~KMemoryBlockDisableMergeAttribute::IpcLeft);
+ }
+ }
+ }
- return block;
+ constexpr KMemoryBlockDisableMergeAttribute GetDisableMergeAttribute() const {
+ return m_disable_merge_attribute;
}
};
static_assert(std::is_trivially_destructible<KMemoryBlock>::value);
diff --git a/src/core/hle/kernel/k_memory_block_manager.cpp b/src/core/hle/kernel/k_memory_block_manager.cpp
index 3ddb9984f..cf4c1e371 100644
--- a/src/core/hle/kernel/k_memory_block_manager.cpp
+++ b/src/core/hle/kernel/k_memory_block_manager.cpp
@@ -2,221 +2,336 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/k_memory_block_manager.h"
-#include "core/hle/kernel/memory_types.h"
namespace Kernel {
-KMemoryBlockManager::KMemoryBlockManager(VAddr start_addr_, VAddr end_addr_)
- : start_addr{start_addr_}, end_addr{end_addr_} {
- const u64 num_pages{(end_addr - start_addr) / PageSize};
- memory_block_tree.emplace_back(start_addr, num_pages, KMemoryState::Free,
- KMemoryPermission::None, KMemoryAttribute::None);
-}
+KMemoryBlockManager::KMemoryBlockManager() = default;
-KMemoryBlockManager::iterator KMemoryBlockManager::FindIterator(VAddr addr) {
- auto node{memory_block_tree.begin()};
- while (node != end()) {
- const VAddr node_end_addr{node->GetNumPages() * PageSize + node->GetAddress()};
- if (node->GetAddress() <= addr && node_end_addr - 1 >= addr) {
- return node;
- }
- node = std::next(node);
- }
- return end();
+Result KMemoryBlockManager::Initialize(VAddr st, VAddr nd, KMemoryBlockSlabManager* slab_manager) {
+ // Allocate a block to encapsulate the address space, insert it into the tree.
+ KMemoryBlock* start_block = slab_manager->Allocate();
+ R_UNLESS(start_block != nullptr, ResultOutOfResource);
+
+ // Set our start and end.
+ m_start_address = st;
+ m_end_address = nd;
+ ASSERT(Common::IsAligned(m_start_address, PageSize));
+ ASSERT(Common::IsAligned(m_end_address, PageSize));
+
+ // Initialize and insert the block.
+ start_block->Initialize(m_start_address, (m_end_address - m_start_address) / PageSize,
+ KMemoryState::Free, KMemoryPermission::None, KMemoryAttribute::None);
+ m_memory_block_tree.insert(*start_block);
+
+ R_SUCCEED();
}
-VAddr KMemoryBlockManager::FindFreeArea(VAddr region_start, std::size_t region_num_pages,
- std::size_t num_pages, std::size_t align,
- std::size_t offset, std::size_t guard_pages) {
- if (num_pages == 0) {
- return {};
+void KMemoryBlockManager::Finalize(KMemoryBlockSlabManager* slab_manager,
+ HostUnmapCallback&& host_unmap_callback) {
+ // Erase every block until we have none left.
+ auto it = m_memory_block_tree.begin();
+ while (it != m_memory_block_tree.end()) {
+ KMemoryBlock* block = std::addressof(*it);
+ it = m_memory_block_tree.erase(it);
+ slab_manager->Free(block);
+ host_unmap_callback(block->GetAddress(), block->GetSize());
}
- const VAddr region_end{region_start + region_num_pages * PageSize};
- const VAddr region_last{region_end - 1};
- for (auto it{FindIterator(region_start)}; it != memory_block_tree.cend(); it++) {
- const auto info{it->GetMemoryInfo()};
- if (region_last < info.GetAddress()) {
- break;
- }
+ ASSERT(m_memory_block_tree.empty());
+}
- if (info.state != KMemoryState::Free) {
- continue;
- }
+VAddr KMemoryBlockManager::FindFreeArea(VAddr region_start, size_t region_num_pages,
+ size_t num_pages, size_t alignment, size_t offset,
+ size_t guard_pages) const {
+ if (num_pages > 0) {
+ const VAddr region_end = region_start + region_num_pages * PageSize;
+ const VAddr region_last = region_end - 1;
+ for (const_iterator it = this->FindIterator(region_start); it != m_memory_block_tree.cend();
+ it++) {
+ const KMemoryInfo info = it->GetMemoryInfo();
+ if (region_last < info.GetAddress()) {
+ break;
+ }
+ if (info.m_state != KMemoryState::Free) {
+ continue;
+ }
- VAddr area{(info.GetAddress() <= region_start) ? region_start : info.GetAddress()};
- area += guard_pages * PageSize;
+ VAddr area = (info.GetAddress() <= region_start) ? region_start : info.GetAddress();
+ area += guard_pages * PageSize;
- const VAddr offset_area{Common::AlignDown(area, align) + offset};
- area = (area <= offset_area) ? offset_area : offset_area + align;
+ const VAddr offset_area = Common::AlignDown(area, alignment) + offset;
+ area = (area <= offset_area) ? offset_area : offset_area + alignment;
- const VAddr area_end{area + num_pages * PageSize + guard_pages * PageSize};
- const VAddr area_last{area_end - 1};
+ const VAddr area_end = area + num_pages * PageSize + guard_pages * PageSize;
+ const VAddr area_last = area_end - 1;
- if (info.GetAddress() <= area && area < area_last && area_last <= region_last &&
- area_last <= info.GetLastAddress()) {
- return area;
+ if (info.GetAddress() <= area && area < area_last && area_last <= region_last &&
+ area_last <= info.GetLastAddress()) {
+ return area;
+ }
}
}
return {};
}
-void KMemoryBlockManager::Update(VAddr addr, std::size_t num_pages, KMemoryState prev_state,
- KMemoryPermission prev_perm, KMemoryAttribute prev_attribute,
- KMemoryState state, KMemoryPermission perm,
- KMemoryAttribute attribute) {
- const VAddr update_end_addr{addr + num_pages * PageSize};
- iterator node{memory_block_tree.begin()};
+void KMemoryBlockManager::CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator* allocator,
+ VAddr address, size_t num_pages) {
+ // Find the iterator now that we've updated.
+ iterator it = this->FindIterator(address);
+ if (address != m_start_address) {
+ it--;
+ }
- prev_attribute |= KMemoryAttribute::IpcAndDeviceMapped;
+ // Coalesce blocks that we can.
+ while (true) {
+ iterator prev = it++;
+ if (it == m_memory_block_tree.end()) {
+ break;
+ }
- while (node != memory_block_tree.end()) {
- KMemoryBlock* block{&(*node)};
- iterator next_node{std::next(node)};
- const VAddr cur_addr{block->GetAddress()};
- const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr};
+ if (prev->CanMergeWith(*it)) {
+ KMemoryBlock* block = std::addressof(*it);
+ m_memory_block_tree.erase(it);
+ prev->Add(*block);
+ allocator->Free(block);
+ it = prev;
+ }
- if (addr < cur_end_addr && cur_addr < update_end_addr) {
- if (!block->HasProperties(prev_state, prev_perm, prev_attribute)) {
- node = next_node;
- continue;
- }
+ if (address + num_pages * PageSize < it->GetMemoryInfo().GetEndAddress()) {
+ break;
+ }
+ }
+}
- iterator new_node{node};
- if (addr > cur_addr) {
- memory_block_tree.insert(node, block->Split(addr));
+void KMemoryBlockManager::Update(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address,
+ size_t num_pages, KMemoryState state, KMemoryPermission perm,
+ KMemoryAttribute attr,
+ KMemoryBlockDisableMergeAttribute set_disable_attr,
+ KMemoryBlockDisableMergeAttribute clear_disable_attr) {
+ // Ensure for auditing that we never end up with an invalid tree.
+ KScopedMemoryBlockManagerAuditor auditor(this);
+ ASSERT(Common::IsAligned(address, PageSize));
+ ASSERT((attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)) ==
+ KMemoryAttribute::None);
+
+ VAddr cur_address = address;
+ size_t remaining_pages = num_pages;
+ iterator it = this->FindIterator(address);
+
+ while (remaining_pages > 0) {
+ const size_t remaining_size = remaining_pages * PageSize;
+ KMemoryInfo cur_info = it->GetMemoryInfo();
+ if (it->HasProperties(state, perm, attr)) {
+ // If we already have the right properties, just advance.
+ if (cur_address + remaining_size < cur_info.GetEndAddress()) {
+ remaining_pages = 0;
+ cur_address += remaining_size;
+ } else {
+ remaining_pages =
+ (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize;
+ cur_address = cur_info.GetEndAddress();
}
+ } else {
+ // If we need to, create a new block before and insert it.
+ if (cur_info.GetAddress() != cur_address) {
+ KMemoryBlock* new_block = allocator->Allocate();
+
+ it->Split(new_block, cur_address);
+ it = m_memory_block_tree.insert(*new_block);
+ it++;
- if (update_end_addr < cur_end_addr) {
- new_node = memory_block_tree.insert(node, block->Split(update_end_addr));
+ cur_info = it->GetMemoryInfo();
+ cur_address = cur_info.GetAddress();
}
- new_node->Update(state, perm, attribute);
+ // If we need to, create a new block after and insert it.
+ if (cur_info.GetSize() > remaining_size) {
+ KMemoryBlock* new_block = allocator->Allocate();
- MergeAdjacent(new_node, next_node);
- }
+ it->Split(new_block, cur_address + remaining_size);
+ it = m_memory_block_tree.insert(*new_block);
- if (cur_end_addr - 1 >= update_end_addr - 1) {
- break;
- }
+ cur_info = it->GetMemoryInfo();
+ }
- node = next_node;
+ // Update block state.
+ it->Update(state, perm, attr, cur_address == address, static_cast<u8>(set_disable_attr),
+ static_cast<u8>(clear_disable_attr));
+ cur_address += cur_info.GetSize();
+ remaining_pages -= cur_info.GetNumPages();
+ }
+ it++;
}
+
+ this->CoalesceForUpdate(allocator, address, num_pages);
}
-void KMemoryBlockManager::Update(VAddr addr, std::size_t num_pages, KMemoryState state,
- KMemoryPermission perm, KMemoryAttribute attribute) {
- const VAddr update_end_addr{addr + num_pages * PageSize};
- iterator node{memory_block_tree.begin()};
+void KMemoryBlockManager::UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allocator,
+ VAddr address, size_t num_pages, KMemoryState test_state,
+ KMemoryPermission test_perm, KMemoryAttribute test_attr,
+ KMemoryState state, KMemoryPermission perm,
+ KMemoryAttribute attr) {
+ // Ensure for auditing that we never end up with an invalid tree.
+ KScopedMemoryBlockManagerAuditor auditor(this);
+ ASSERT(Common::IsAligned(address, PageSize));
+ ASSERT((attr & (KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared)) ==
+ KMemoryAttribute::None);
+
+ VAddr cur_address = address;
+ size_t remaining_pages = num_pages;
+ iterator it = this->FindIterator(address);
+
+ while (remaining_pages > 0) {
+ const size_t remaining_size = remaining_pages * PageSize;
+ KMemoryInfo cur_info = it->GetMemoryInfo();
+ if (it->HasProperties(test_state, test_perm, test_attr) &&
+ !it->HasProperties(state, perm, attr)) {
+ // If we need to, create a new block before and insert it.
+ if (cur_info.GetAddress() != cur_address) {
+ KMemoryBlock* new_block = allocator->Allocate();
+
+ it->Split(new_block, cur_address);
+ it = m_memory_block_tree.insert(*new_block);
+ it++;
+
+ cur_info = it->GetMemoryInfo();
+ cur_address = cur_info.GetAddress();
+ }
- while (node != memory_block_tree.end()) {
- KMemoryBlock* block{&(*node)};
- iterator next_node{std::next(node)};
- const VAddr cur_addr{block->GetAddress()};
- const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr};
+ // If we need to, create a new block after and insert it.
+ if (cur_info.GetSize() > remaining_size) {
+ KMemoryBlock* new_block = allocator->Allocate();
- if (addr < cur_end_addr && cur_addr < update_end_addr) {
- iterator new_node{node};
+ it->Split(new_block, cur_address + remaining_size);
+ it = m_memory_block_tree.insert(*new_block);
- if (addr > cur_addr) {
- memory_block_tree.insert(node, block->Split(addr));
+ cur_info = it->GetMemoryInfo();
}
- if (update_end_addr < cur_end_addr) {
- new_node = memory_block_tree.insert(node, block->Split(update_end_addr));
+ // Update block state.
+ it->Update(state, perm, attr, false, 0, 0);
+ cur_address += cur_info.GetSize();
+ remaining_pages -= cur_info.GetNumPages();
+ } else {
+ // If we already have the right properties, just advance.
+ if (cur_address + remaining_size < cur_info.GetEndAddress()) {
+ remaining_pages = 0;
+ cur_address += remaining_size;
+ } else {
+ remaining_pages =
+ (cur_address + remaining_size - cur_info.GetEndAddress()) / PageSize;
+ cur_address = cur_info.GetEndAddress();
}
-
- new_node->Update(state, perm, attribute);
-
- MergeAdjacent(new_node, next_node);
- }
-
- if (cur_end_addr - 1 >= update_end_addr - 1) {
- break;
}
-
- node = next_node;
+ it++;
}
+
+ this->CoalesceForUpdate(allocator, address, num_pages);
}
-void KMemoryBlockManager::UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func,
+void KMemoryBlockManager::UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address,
+ size_t num_pages, MemoryBlockLockFunction lock_func,
KMemoryPermission perm) {
- const VAddr update_end_addr{addr + num_pages * PageSize};
- iterator node{memory_block_tree.begin()};
+ // Ensure for auditing that we never end up with an invalid tree.
+ KScopedMemoryBlockManagerAuditor auditor(this);
+ ASSERT(Common::IsAligned(address, PageSize));
- while (node != memory_block_tree.end()) {
- KMemoryBlock* block{&(*node)};
- iterator next_node{std::next(node)};
- const VAddr cur_addr{block->GetAddress()};
- const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr};
+ VAddr cur_address = address;
+ size_t remaining_pages = num_pages;
+ iterator it = this->FindIterator(address);
- if (addr < cur_end_addr && cur_addr < update_end_addr) {
- iterator new_node{node};
+ const VAddr end_address = address + (num_pages * PageSize);
- if (addr > cur_addr) {
- memory_block_tree.insert(node, block->Split(addr));
- }
+ while (remaining_pages > 0) {
+ const size_t remaining_size = remaining_pages * PageSize;
+ KMemoryInfo cur_info = it->GetMemoryInfo();
- if (update_end_addr < cur_end_addr) {
- new_node = memory_block_tree.insert(node, block->Split(update_end_addr));
- }
+ // If we need to, create a new block before and insert it.
+ if (cur_info.m_address != cur_address) {
+ KMemoryBlock* new_block = allocator->Allocate();
- lock_func(new_node, perm);
+ it->Split(new_block, cur_address);
+ it = m_memory_block_tree.insert(*new_block);
+ it++;
- MergeAdjacent(new_node, next_node);
+ cur_info = it->GetMemoryInfo();
+ cur_address = cur_info.GetAddress();
}
- if (cur_end_addr - 1 >= update_end_addr - 1) {
- break;
+ if (cur_info.GetSize() > remaining_size) {
+ // If we need to, create a new block after and insert it.
+ KMemoryBlock* new_block = allocator->Allocate();
+
+ it->Split(new_block, cur_address + remaining_size);
+ it = m_memory_block_tree.insert(*new_block);
+
+ cur_info = it->GetMemoryInfo();
}
- node = next_node;
+ // Call the locked update function.
+ (std::addressof(*it)->*lock_func)(perm, cur_info.GetAddress() == address,
+ cur_info.GetEndAddress() == end_address);
+ cur_address += cur_info.GetSize();
+ remaining_pages -= cur_info.GetNumPages();
+ it++;
}
-}
-void KMemoryBlockManager::IterateForRange(VAddr start, VAddr end, IterateFunc&& func) {
- const_iterator it{FindIterator(start)};
- KMemoryInfo info{};
- do {
- info = it->GetMemoryInfo();
- func(info);
- it = std::next(it);
- } while (info.addr + info.size - 1 < end - 1 && it != cend());
+ this->CoalesceForUpdate(allocator, address, num_pages);
}
-void KMemoryBlockManager::MergeAdjacent(iterator it, iterator& next_it) {
- KMemoryBlock* block{&(*it)};
-
- auto EraseIt = [&](const iterator it_to_erase) {
- if (next_it == it_to_erase) {
- next_it = std::next(next_it);
+// Debug.
+bool KMemoryBlockManager::CheckState() const {
+ // Loop over every block, ensuring that we are sorted and coalesced.
+ auto it = m_memory_block_tree.cbegin();
+ auto prev = it++;
+ while (it != m_memory_block_tree.cend()) {
+ const KMemoryInfo prev_info = prev->GetMemoryInfo();
+ const KMemoryInfo cur_info = it->GetMemoryInfo();
+
+ // Sequential blocks which can be merged should be merged.
+ if (prev->CanMergeWith(*it)) {
+ return false;
}
- memory_block_tree.erase(it_to_erase);
- };
- if (it != memory_block_tree.begin()) {
- KMemoryBlock* prev{&(*std::prev(it))};
-
- if (block->HasSameProperties(*prev)) {
- const iterator prev_it{std::prev(it)};
+ // Sequential blocks should be sequential.
+ if (prev_info.GetEndAddress() != cur_info.GetAddress()) {
+ return false;
+ }
- prev->Add(block->GetNumPages());
- EraseIt(it);
+ // If the block is ipc locked, it must have a count.
+ if ((cur_info.m_attribute & KMemoryAttribute::IpcLocked) != KMemoryAttribute::None &&
+ cur_info.m_ipc_lock_count == 0) {
+ return false;
+ }
- it = prev_it;
- block = prev;
+ // If the block is device shared, it must have a count.
+ if ((cur_info.m_attribute & KMemoryAttribute::DeviceShared) != KMemoryAttribute::None &&
+ cur_info.m_device_use_count == 0) {
+ return false;
}
+
+ // Advance the iterator.
+ prev = it++;
}
- if (it != cend()) {
- const KMemoryBlock* const next{&(*std::next(it))};
+ // Our loop will miss checking the last block, potentially, so check it.
+ if (prev != m_memory_block_tree.cend()) {
+ const KMemoryInfo prev_info = prev->GetMemoryInfo();
+ // If the block is ipc locked, it must have a count.
+ if ((prev_info.m_attribute & KMemoryAttribute::IpcLocked) != KMemoryAttribute::None &&
+ prev_info.m_ipc_lock_count == 0) {
+ return false;
+ }
- if (block->HasSameProperties(*next)) {
- block->Add(next->GetNumPages());
- EraseIt(std::next(it));
+ // If the block is device shared, it must have a count.
+ if ((prev_info.m_attribute & KMemoryAttribute::DeviceShared) != KMemoryAttribute::None &&
+ prev_info.m_device_use_count == 0) {
+ return false;
}
}
+
+ return true;
}
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_memory_block_manager.h b/src/core/hle/kernel/k_memory_block_manager.h
index e14741b89..9b5873883 100644
--- a/src/core/hle/kernel/k_memory_block_manager.h
+++ b/src/core/hle/kernel/k_memory_block_manager.h
@@ -4,63 +4,154 @@
#pragma once
#include <functional>
-#include <list>
+#include "common/common_funcs.h"
#include "common/common_types.h"
+#include "core/hle/kernel/k_dynamic_resource_manager.h"
#include "core/hle/kernel/k_memory_block.h"
namespace Kernel {
+class KMemoryBlockManagerUpdateAllocator {
+public:
+ static constexpr size_t MaxBlocks = 2;
+
+private:
+ KMemoryBlock* m_blocks[MaxBlocks];
+ size_t m_index;
+ KMemoryBlockSlabManager* m_slab_manager;
+
+private:
+ Result Initialize(size_t num_blocks) {
+ // Check num blocks.
+ ASSERT(num_blocks <= MaxBlocks);
+
+ // Set index.
+ m_index = MaxBlocks - num_blocks;
+
+ // Allocate the blocks.
+ for (size_t i = 0; i < num_blocks && i < MaxBlocks; ++i) {
+ m_blocks[m_index + i] = m_slab_manager->Allocate();
+ R_UNLESS(m_blocks[m_index + i] != nullptr, ResultOutOfResource);
+ }
+
+ R_SUCCEED();
+ }
+
+public:
+ KMemoryBlockManagerUpdateAllocator(Result* out_result, KMemoryBlockSlabManager* sm,
+ size_t num_blocks = MaxBlocks)
+ : m_blocks(), m_index(MaxBlocks), m_slab_manager(sm) {
+ *out_result = this->Initialize(num_blocks);
+ }
+
+ ~KMemoryBlockManagerUpdateAllocator() {
+ for (const auto& block : m_blocks) {
+ if (block != nullptr) {
+ m_slab_manager->Free(block);
+ }
+ }
+ }
+
+ KMemoryBlock* Allocate() {
+ ASSERT(m_index < MaxBlocks);
+ ASSERT(m_blocks[m_index] != nullptr);
+ KMemoryBlock* block = nullptr;
+ std::swap(block, m_blocks[m_index++]);
+ return block;
+ }
+
+ void Free(KMemoryBlock* block) {
+ ASSERT(m_index <= MaxBlocks);
+ ASSERT(block != nullptr);
+ if (m_index == 0) {
+ m_slab_manager->Free(block);
+ } else {
+ m_blocks[--m_index] = block;
+ }
+ }
+};
+
class KMemoryBlockManager final {
public:
- using MemoryBlockTree = std::list<KMemoryBlock>;
+ using MemoryBlockTree =
+ Common::IntrusiveRedBlackTreeBaseTraits<KMemoryBlock>::TreeType<KMemoryBlock>;
+ using MemoryBlockLockFunction = void (KMemoryBlock::*)(KMemoryPermission new_perm, bool left,
+ bool right);
using iterator = MemoryBlockTree::iterator;
using const_iterator = MemoryBlockTree::const_iterator;
public:
- KMemoryBlockManager(VAddr start_addr_, VAddr end_addr_);
+ KMemoryBlockManager();
+
+ using HostUnmapCallback = std::function<void(VAddr, u64)>;
+
+ Result Initialize(VAddr st, VAddr nd, KMemoryBlockSlabManager* slab_manager);
+ void Finalize(KMemoryBlockSlabManager* slab_manager, HostUnmapCallback&& host_unmap_callback);
iterator end() {
- return memory_block_tree.end();
+ return m_memory_block_tree.end();
}
const_iterator end() const {
- return memory_block_tree.end();
+ return m_memory_block_tree.end();
}
const_iterator cend() const {
- return memory_block_tree.cend();
+ return m_memory_block_tree.cend();
}
- iterator FindIterator(VAddr addr);
+ VAddr FindFreeArea(VAddr region_start, size_t region_num_pages, size_t num_pages,
+ size_t alignment, size_t offset, size_t guard_pages) const;
- VAddr FindFreeArea(VAddr region_start, std::size_t region_num_pages, std::size_t num_pages,
- std::size_t align, std::size_t offset, std::size_t guard_pages);
+ void Update(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address, size_t num_pages,
+ KMemoryState state, KMemoryPermission perm, KMemoryAttribute attr,
+ KMemoryBlockDisableMergeAttribute set_disable_attr,
+ KMemoryBlockDisableMergeAttribute clear_disable_attr);
+ void UpdateLock(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address, size_t num_pages,
+ MemoryBlockLockFunction lock_func, KMemoryPermission perm);
- void Update(VAddr addr, std::size_t num_pages, KMemoryState prev_state,
- KMemoryPermission prev_perm, KMemoryAttribute prev_attribute, KMemoryState state,
- KMemoryPermission perm, KMemoryAttribute attribute);
+ void UpdateIfMatch(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address,
+ size_t num_pages, KMemoryState test_state, KMemoryPermission test_perm,
+ KMemoryAttribute test_attr, KMemoryState state, KMemoryPermission perm,
+ KMemoryAttribute attr);
- void Update(VAddr addr, std::size_t num_pages, KMemoryState state,
- KMemoryPermission perm = KMemoryPermission::None,
- KMemoryAttribute attribute = KMemoryAttribute::None);
-
- using LockFunc = std::function<void(iterator, KMemoryPermission)>;
- void UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func,
- KMemoryPermission perm);
+ iterator FindIterator(VAddr address) const {
+ return m_memory_block_tree.find(KMemoryBlock(
+ address, 1, KMemoryState::Free, KMemoryPermission::None, KMemoryAttribute::None));
+ }
- using IterateFunc = std::function<void(const KMemoryInfo&)>;
- void IterateForRange(VAddr start, VAddr end, IterateFunc&& func);
+ const KMemoryBlock* FindBlock(VAddr address) const {
+ if (const_iterator it = this->FindIterator(address); it != m_memory_block_tree.end()) {
+ return std::addressof(*it);
+ }
- KMemoryBlock& FindBlock(VAddr addr) {
- return *FindIterator(addr);
+ return nullptr;
}
+ // Debug.
+ bool CheckState() const;
+
private:
- void MergeAdjacent(iterator it, iterator& next_it);
+ void CoalesceForUpdate(KMemoryBlockManagerUpdateAllocator* allocator, VAddr address,
+ size_t num_pages);
- [[maybe_unused]] const VAddr start_addr;
- [[maybe_unused]] const VAddr end_addr;
+ MemoryBlockTree m_memory_block_tree;
+ VAddr m_start_address{};
+ VAddr m_end_address{};
+};
- MemoryBlockTree memory_block_tree;
+class KScopedMemoryBlockManagerAuditor {
+public:
+ explicit KScopedMemoryBlockManagerAuditor(KMemoryBlockManager* m) : m_manager(m) {
+ ASSERT(m_manager->CheckState());
+ }
+ explicit KScopedMemoryBlockManagerAuditor(KMemoryBlockManager& m)
+ : KScopedMemoryBlockManagerAuditor(std::addressof(m)) {}
+ ~KScopedMemoryBlockManagerAuditor() {
+ ASSERT(m_manager->CheckState());
+ }
+
+private:
+ KMemoryBlockManager* m_manager;
};
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_memory_manager.cpp b/src/core/hle/kernel/k_memory_manager.cpp
index 5b0a9963a..646711505 100644
--- a/src/core/hle/kernel/k_memory_manager.cpp
+++ b/src/core/hle/kernel/k_memory_manager.cpp
@@ -331,7 +331,7 @@ Result KMemoryManager::AllocateAndOpenForProcess(KPageGroup* out, size_t num_pag
// Set all the allocated memory.
for (const auto& block : out->Nodes()) {
- std::memset(system.DeviceMemory().GetPointer(block.GetAddress()), fill_pattern,
+ std::memset(system.DeviceMemory().GetPointer<void>(block.GetAddress()), fill_pattern,
block.GetSize());
}
diff --git a/src/core/hle/kernel/k_page_buffer.cpp b/src/core/hle/kernel/k_page_buffer.cpp
index 1a0bf4439..0c16dded4 100644
--- a/src/core/hle/kernel/k_page_buffer.cpp
+++ b/src/core/hle/kernel/k_page_buffer.cpp
@@ -12,7 +12,7 @@ namespace Kernel {
KPageBuffer* KPageBuffer::FromPhysicalAddress(Core::System& system, PAddr phys_addr) {
ASSERT(Common::IsAligned(phys_addr, PageSize));
- return reinterpret_cast<KPageBuffer*>(system.DeviceMemory().GetPointer(phys_addr));
+ return system.DeviceMemory().GetPointer<KPageBuffer>(phys_addr);
}
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_page_buffer.h b/src/core/hle/kernel/k_page_buffer.h
index 7e50dc1d1..aef06e213 100644
--- a/src/core/hle/kernel/k_page_buffer.h
+++ b/src/core/hle/kernel/k_page_buffer.h
@@ -13,6 +13,7 @@ namespace Kernel {
class KPageBuffer final : public KSlabAllocated<KPageBuffer> {
public:
+ explicit KPageBuffer(KernelCore&) {}
KPageBuffer() = default;
static KPageBuffer* FromPhysicalAddress(Core::System& system, PAddr phys_addr);
diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index d975de844..307e491cb 100644
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -25,7 +25,7 @@ namespace {
using namespace Common::Literals;
-constexpr std::size_t GetAddressSpaceWidthFromType(FileSys::ProgramAddressSpaceType as_type) {
+constexpr size_t GetAddressSpaceWidthFromType(FileSys::ProgramAddressSpaceType as_type) {
switch (as_type) {
case FileSys::ProgramAddressSpaceType::Is32Bit:
case FileSys::ProgramAddressSpaceType::Is32BitNoMap:
@@ -43,27 +43,29 @@ constexpr std::size_t GetAddressSpaceWidthFromType(FileSys::ProgramAddressSpaceT
} // namespace
KPageTable::KPageTable(Core::System& system_)
- : general_lock{system_.Kernel()}, map_physical_memory_lock{system_.Kernel()}, system{system_} {}
+ : m_general_lock{system_.Kernel()},
+ m_map_physical_memory_lock{system_.Kernel()}, m_system{system_} {}
KPageTable::~KPageTable() = default;
Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
- VAddr code_addr, std::size_t code_size,
+ VAddr code_addr, size_t code_size,
+ KMemoryBlockSlabManager* mem_block_slab_manager,
KMemoryManager::Pool pool) {
const auto GetSpaceStart = [this](KAddressSpaceInfo::Type type) {
- return KAddressSpaceInfo::GetAddressSpaceStart(address_space_width, type);
+ return KAddressSpaceInfo::GetAddressSpaceStart(m_address_space_width, type);
};
const auto GetSpaceSize = [this](KAddressSpaceInfo::Type type) {
- return KAddressSpaceInfo::GetAddressSpaceSize(address_space_width, type);
+ return KAddressSpaceInfo::GetAddressSpaceSize(m_address_space_width, type);
};
// Set our width and heap/alias sizes
- address_space_width = GetAddressSpaceWidthFromType(as_type);
+ m_address_space_width = GetAddressSpaceWidthFromType(as_type);
const VAddr start = 0;
- const VAddr end{1ULL << address_space_width};
- std::size_t alias_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Alias)};
- std::size_t heap_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Heap)};
+ const VAddr end{1ULL << m_address_space_width};
+ size_t alias_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Alias)};
+ size_t heap_region_size{GetSpaceSize(KAddressSpaceInfo::Type::Heap)};
ASSERT(code_addr < code_addr + code_size);
ASSERT(code_addr + code_size - 1 <= end - 1);
@@ -75,66 +77,65 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
}
// Set code regions and determine remaining
- constexpr std::size_t RegionAlignment{2_MiB};
+ constexpr size_t RegionAlignment{2_MiB};
VAddr process_code_start{};
VAddr process_code_end{};
- std::size_t stack_region_size{};
- std::size_t kernel_map_region_size{};
+ size_t stack_region_size{};
+ size_t kernel_map_region_size{};
- if (address_space_width == 39) {
+ if (m_address_space_width == 39) {
alias_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Alias);
heap_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Heap);
stack_region_size = GetSpaceSize(KAddressSpaceInfo::Type::Stack);
kernel_map_region_size = GetSpaceSize(KAddressSpaceInfo::Type::MapSmall);
- code_region_start = GetSpaceStart(KAddressSpaceInfo::Type::Map39Bit);
- code_region_end = code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::Map39Bit);
- alias_code_region_start = code_region_start;
- alias_code_region_end = code_region_end;
+ m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type::Map39Bit);
+ m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::Map39Bit);
+ m_alias_code_region_start = m_code_region_start;
+ m_alias_code_region_end = m_code_region_end;
process_code_start = Common::AlignDown(code_addr, RegionAlignment);
process_code_end = Common::AlignUp(code_addr + code_size, RegionAlignment);
} else {
stack_region_size = 0;
kernel_map_region_size = 0;
- code_region_start = GetSpaceStart(KAddressSpaceInfo::Type::MapSmall);
- code_region_end = code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::MapSmall);
- stack_region_start = code_region_start;
- alias_code_region_start = code_region_start;
- alias_code_region_end = GetSpaceStart(KAddressSpaceInfo::Type::MapLarge) +
- GetSpaceSize(KAddressSpaceInfo::Type::MapLarge);
- stack_region_end = code_region_end;
- kernel_map_region_start = code_region_start;
- kernel_map_region_end = code_region_end;
- process_code_start = code_region_start;
- process_code_end = code_region_end;
+ m_code_region_start = GetSpaceStart(KAddressSpaceInfo::Type::MapSmall);
+ m_code_region_end = m_code_region_start + GetSpaceSize(KAddressSpaceInfo::Type::MapSmall);
+ m_stack_region_start = m_code_region_start;
+ m_alias_code_region_start = m_code_region_start;
+ m_alias_code_region_end = GetSpaceStart(KAddressSpaceInfo::Type::MapLarge) +
+ GetSpaceSize(KAddressSpaceInfo::Type::MapLarge);
+ m_stack_region_end = m_code_region_end;
+ m_kernel_map_region_start = m_code_region_start;
+ m_kernel_map_region_end = m_code_region_end;
+ process_code_start = m_code_region_start;
+ process_code_end = m_code_region_end;
}
// Set other basic fields
- is_aslr_enabled = enable_aslr;
- address_space_start = start;
- address_space_end = end;
- is_kernel = false;
+ m_enable_aslr = enable_aslr;
+ m_enable_device_address_space_merge = false;
+ m_address_space_start = start;
+ m_address_space_end = end;
+ m_is_kernel = false;
+ m_memory_block_slab_manager = mem_block_slab_manager;
// Determine the region we can place our undetermineds in
VAddr alloc_start{};
- std::size_t alloc_size{};
- if ((process_code_start - code_region_start) >= (end - process_code_end)) {
- alloc_start = code_region_start;
- alloc_size = process_code_start - code_region_start;
+ size_t alloc_size{};
+ if ((process_code_start - m_code_region_start) >= (end - process_code_end)) {
+ alloc_start = m_code_region_start;
+ alloc_size = process_code_start - m_code_region_start;
} else {
alloc_start = process_code_end;
alloc_size = end - process_code_end;
}
- const std::size_t needed_size{
- (alias_region_size + heap_region_size + stack_region_size + kernel_map_region_size)};
- if (alloc_size < needed_size) {
- ASSERT(false);
- return ResultOutOfMemory;
- }
+ const size_t needed_size =
+ (alias_region_size + heap_region_size + stack_region_size + kernel_map_region_size);
+ R_UNLESS(alloc_size >= needed_size, ResultOutOfMemory);
- const std::size_t remaining_size{alloc_size - needed_size};
+ const size_t remaining_size{alloc_size - needed_size};
// Determine random placements for each region
- std::size_t alias_rnd{}, heap_rnd{}, stack_rnd{}, kmap_rnd{};
+ size_t alias_rnd{}, heap_rnd{}, stack_rnd{}, kmap_rnd{};
if (enable_aslr) {
alias_rnd = KSystemControl::GenerateRandomRange(0, remaining_size / RegionAlignment) *
RegionAlignment;
@@ -147,117 +148,130 @@ Result KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type
}
// Setup heap and alias regions
- alias_region_start = alloc_start + alias_rnd;
- alias_region_end = alias_region_start + alias_region_size;
- heap_region_start = alloc_start + heap_rnd;
- heap_region_end = heap_region_start + heap_region_size;
+ m_alias_region_start = alloc_start + alias_rnd;
+ m_alias_region_end = m_alias_region_start + alias_region_size;
+ m_heap_region_start = alloc_start + heap_rnd;
+ m_heap_region_end = m_heap_region_start + heap_region_size;
if (alias_rnd <= heap_rnd) {
- heap_region_start += alias_region_size;
- heap_region_end += alias_region_size;
+ m_heap_region_start += alias_region_size;
+ m_heap_region_end += alias_region_size;
} else {
- alias_region_start += heap_region_size;
- alias_region_end += heap_region_size;
+ m_alias_region_start += heap_region_size;
+ m_alias_region_end += heap_region_size;
}
// Setup stack region
if (stack_region_size) {
- stack_region_start = alloc_start + stack_rnd;
- stack_region_end = stack_region_start + stack_region_size;
+ m_stack_region_start = alloc_start + stack_rnd;
+ m_stack_region_end = m_stack_region_start + stack_region_size;
if (alias_rnd < stack_rnd) {
- stack_region_start += alias_region_size;
- stack_region_end += alias_region_size;
+ m_stack_region_start += alias_region_size;
+ m_stack_region_end += alias_region_size;
} else {
- alias_region_start += stack_region_size;
- alias_region_end += stack_region_size;
+ m_alias_region_start += stack_region_size;
+ m_alias_region_end += stack_region_size;
}
if (heap_rnd < stack_rnd) {
- stack_region_start += heap_region_size;
- stack_region_end += heap_region_size;
+ m_stack_region_start += heap_region_size;
+ m_stack_region_end += heap_region_size;
} else {
- heap_region_start += stack_region_size;
- heap_region_end += stack_region_size;
+ m_heap_region_start += stack_region_size;
+ m_heap_region_end += stack_region_size;
}
}
// Setup kernel map region
if (kernel_map_region_size) {
- kernel_map_region_start = alloc_start + kmap_rnd;
- kernel_map_region_end = kernel_map_region_start + kernel_map_region_size;
+ m_kernel_map_region_start = alloc_start + kmap_rnd;
+ m_kernel_map_region_end = m_kernel_map_region_start + kernel_map_region_size;
if (alias_rnd < kmap_rnd) {
- kernel_map_region_start += alias_region_size;
- kernel_map_region_end += alias_region_size;
+ m_kernel_map_region_start += alias_region_size;
+ m_kernel_map_region_end += alias_region_size;
} else {
- alias_region_start += kernel_map_region_size;
- alias_region_end += kernel_map_region_size;
+ m_alias_region_start += kernel_map_region_size;
+ m_alias_region_end += kernel_map_region_size;
}
if (heap_rnd < kmap_rnd) {
- kernel_map_region_start += heap_region_size;
- kernel_map_region_end += heap_region_size;
+ m_kernel_map_region_start += heap_region_size;
+ m_kernel_map_region_end += heap_region_size;
} else {
- heap_region_start += kernel_map_region_size;
- heap_region_end += kernel_map_region_size;
+ m_heap_region_start += kernel_map_region_size;
+ m_heap_region_end += kernel_map_region_size;
}
if (stack_region_size) {
if (stack_rnd < kmap_rnd) {
- kernel_map_region_start += stack_region_size;
- kernel_map_region_end += stack_region_size;
+ m_kernel_map_region_start += stack_region_size;
+ m_kernel_map_region_end += stack_region_size;
} else {
- stack_region_start += kernel_map_region_size;
- stack_region_end += kernel_map_region_size;
+ m_stack_region_start += kernel_map_region_size;
+ m_stack_region_end += kernel_map_region_size;
}
}
}
// Set heap members
- current_heap_end = heap_region_start;
- max_heap_size = 0;
- max_physical_memory_size = 0;
+ m_current_heap_end = m_heap_region_start;
+ m_max_heap_size = 0;
+ m_max_physical_memory_size = 0;
// Ensure that we regions inside our address space
auto IsInAddressSpace = [&](VAddr addr) {
- return address_space_start <= addr && addr <= address_space_end;
+ return m_address_space_start <= addr && addr <= m_address_space_end;
};
- ASSERT(IsInAddressSpace(alias_region_start));
- ASSERT(IsInAddressSpace(alias_region_end));
- ASSERT(IsInAddressSpace(heap_region_start));
- ASSERT(IsInAddressSpace(heap_region_end));
- ASSERT(IsInAddressSpace(stack_region_start));
- ASSERT(IsInAddressSpace(stack_region_end));
- ASSERT(IsInAddressSpace(kernel_map_region_start));
- ASSERT(IsInAddressSpace(kernel_map_region_end));
+ ASSERT(IsInAddressSpace(m_alias_region_start));
+ ASSERT(IsInAddressSpace(m_alias_region_end));
+ ASSERT(IsInAddressSpace(m_heap_region_start));
+ ASSERT(IsInAddressSpace(m_heap_region_end));
+ ASSERT(IsInAddressSpace(m_stack_region_start));
+ ASSERT(IsInAddressSpace(m_stack_region_end));
+ ASSERT(IsInAddressSpace(m_kernel_map_region_start));
+ ASSERT(IsInAddressSpace(m_kernel_map_region_end));
// Ensure that we selected regions that don't overlap
- const VAddr alias_start{alias_region_start};
- const VAddr alias_last{alias_region_end - 1};
- const VAddr heap_start{heap_region_start};
- const VAddr heap_last{heap_region_end - 1};
- const VAddr stack_start{stack_region_start};
- const VAddr stack_last{stack_region_end - 1};
- const VAddr kmap_start{kernel_map_region_start};
- const VAddr kmap_last{kernel_map_region_end - 1};
+ const VAddr alias_start{m_alias_region_start};
+ const VAddr alias_last{m_alias_region_end - 1};
+ const VAddr heap_start{m_heap_region_start};
+ const VAddr heap_last{m_heap_region_end - 1};
+ const VAddr stack_start{m_stack_region_start};
+ const VAddr stack_last{m_stack_region_end - 1};
+ const VAddr kmap_start{m_kernel_map_region_start};
+ const VAddr kmap_last{m_kernel_map_region_end - 1};
ASSERT(alias_last < heap_start || heap_last < alias_start);
ASSERT(alias_last < stack_start || stack_last < alias_start);
ASSERT(alias_last < kmap_start || kmap_last < alias_start);
ASSERT(heap_last < stack_start || stack_last < heap_start);
ASSERT(heap_last < kmap_start || kmap_last < heap_start);
- current_heap_end = heap_region_start;
- max_heap_size = 0;
- mapped_physical_memory_size = 0;
- memory_pool = pool;
+ m_current_heap_end = m_heap_region_start;
+ m_max_heap_size = 0;
+ m_mapped_physical_memory_size = 0;
+ m_memory_pool = pool;
+
+ m_page_table_impl = std::make_unique<Common::PageTable>();
+ m_page_table_impl->Resize(m_address_space_width, PageBits);
+
+ // Initialize our memory block manager.
+ R_RETURN(m_memory_block_manager.Initialize(m_address_space_start, m_address_space_end,
+ m_memory_block_slab_manager));
+}
- page_table_impl.Resize(address_space_width, PageBits);
+void KPageTable::Finalize() {
+ // Finalize memory blocks.
+ m_memory_block_manager.Finalize(m_memory_block_slab_manager, [&](VAddr addr, u64 size) {
+ m_system.Memory().UnmapRegion(*m_page_table_impl, addr, size);
+ });
- return InitializeMemoryLayout(start, end);
+ // Close the backing page table, as the destructor is not called for guest objects.
+ m_page_table_impl.reset();
}
-Result KPageTable::MapProcessCode(VAddr addr, std::size_t num_pages, KMemoryState state,
+Result KPageTable::MapProcessCode(VAddr addr, size_t num_pages, KMemoryState state,
KMemoryPermission perm) {
const u64 size{num_pages * PageSize};
@@ -265,52 +279,76 @@ Result KPageTable::MapProcessCode(VAddr addr, std::size_t num_pages, KMemoryStat
R_UNLESS(this->CanContain(addr, size, state), ResultInvalidCurrentMemory);
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Verify that the destination memory is unmapped.
R_TRY(this->CheckMemoryState(addr, size, KMemoryState::All, KMemoryState::Free,
KMemoryPermission::None, KMemoryPermission::None,
KMemoryAttribute::None, KMemoryAttribute::None));
+
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager);
+
+ // Allocate and open.
KPageGroup pg;
- R_TRY(system.Kernel().MemoryManager().AllocateAndOpen(
+ R_TRY(m_system.Kernel().MemoryManager().AllocateAndOpen(
&pg, num_pages,
- KMemoryManager::EncodeOption(KMemoryManager::Pool::Application, allocation_option)));
+ KMemoryManager::EncodeOption(KMemoryManager::Pool::Application, m_allocation_option)));
R_TRY(Operate(addr, num_pages, pg, OperationType::MapGroup));
- block_manager->Update(addr, num_pages, state, perm);
+ // Update the blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, state, perm,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
- return ResultSuccess;
+ R_SUCCEED();
}
-Result KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size) {
+Result KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, size_t size) {
// Validate the mapping request.
R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode),
ResultInvalidMemoryRegion);
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Verify that the source memory is normal heap.
KMemoryState src_state{};
KMemoryPermission src_perm{};
- std::size_t num_src_allocator_blocks{};
+ size_t num_src_allocator_blocks{};
R_TRY(this->CheckMemoryState(&src_state, &src_perm, nullptr, &num_src_allocator_blocks,
src_address, size, KMemoryState::All, KMemoryState::Normal,
KMemoryPermission::All, KMemoryPermission::UserReadWrite,
KMemoryAttribute::All, KMemoryAttribute::None));
// Verify that the destination memory is unmapped.
- std::size_t num_dst_allocator_blocks{};
+ size_t num_dst_allocator_blocks{};
R_TRY(this->CheckMemoryState(&num_dst_allocator_blocks, dst_address, size, KMemoryState::All,
KMemoryState::Free, KMemoryPermission::None,
KMemoryPermission::None, KMemoryAttribute::None,
KMemoryAttribute::None));
+ // Create an update allocator for the source.
+ Result src_allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator src_allocator(std::addressof(src_allocator_result),
+ m_memory_block_slab_manager,
+ num_src_allocator_blocks);
+ R_TRY(src_allocator_result);
+
+ // Create an update allocator for the destination.
+ Result dst_allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator dst_allocator(std::addressof(dst_allocator_result),
+ m_memory_block_slab_manager,
+ num_dst_allocator_blocks);
+ R_TRY(dst_allocator_result);
+
// Map the code memory.
{
// Determine the number of pages being operated on.
- const std::size_t num_pages = size / PageSize;
+ const size_t num_pages = size / PageSize;
// Create page groups for the memory being mapped.
KPageGroup pg;
@@ -335,33 +373,37 @@ Result KPageTable::MapCodeMemory(VAddr dst_address, VAddr src_address, std::size
unprot_guard.Cancel();
// Apply the memory block updates.
- block_manager->Update(src_address, num_pages, src_state, new_perm,
- KMemoryAttribute::Locked);
- block_manager->Update(dst_address, num_pages, KMemoryState::AliasCode, new_perm,
- KMemoryAttribute::None);
+ m_memory_block_manager.Update(std::addressof(src_allocator), src_address, num_pages,
+ src_state, new_perm, KMemoryAttribute::Locked,
+ KMemoryBlockDisableMergeAttribute::Locked,
+ KMemoryBlockDisableMergeAttribute::None);
+ m_memory_block_manager.Update(std::addressof(dst_allocator), dst_address, num_pages,
+ KMemoryState::AliasCode, new_perm, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
}
- return ResultSuccess;
+ R_SUCCEED();
}
-Result KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size,
+Result KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, size_t size,
ICacheInvalidationStrategy icache_invalidation_strategy) {
// Validate the mapping request.
R_UNLESS(this->CanContain(dst_address, size, KMemoryState::AliasCode),
ResultInvalidMemoryRegion);
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Verify that the source memory is locked normal heap.
- std::size_t num_src_allocator_blocks{};
+ size_t num_src_allocator_blocks{};
R_TRY(this->CheckMemoryState(std::addressof(num_src_allocator_blocks), src_address, size,
KMemoryState::All, KMemoryState::Normal, KMemoryPermission::None,
KMemoryPermission::None, KMemoryAttribute::All,
KMemoryAttribute::Locked));
// Verify that the destination memory is aliasable code.
- std::size_t num_dst_allocator_blocks{};
+ size_t num_dst_allocator_blocks{};
R_TRY(this->CheckMemoryStateContiguous(
std::addressof(num_dst_allocator_blocks), dst_address, size, KMemoryState::FlagCanCodeAlias,
KMemoryState::FlagCanCodeAlias, KMemoryPermission::None, KMemoryPermission::None,
@@ -370,7 +412,7 @@ Result KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::si
// Determine whether any pages being unmapped are code.
bool any_code_pages = false;
{
- KMemoryBlockManager::const_iterator it = block_manager->FindIterator(dst_address);
+ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(dst_address);
while (true) {
// Get the memory info.
const KMemoryInfo info = it->GetMemoryInfo();
@@ -396,9 +438,9 @@ Result KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::si
SCOPE_EXIT({
if (reprotected_pages && any_code_pages) {
if (icache_invalidation_strategy == ICacheInvalidationStrategy::InvalidateRange) {
- system.InvalidateCpuInstructionCacheRange(dst_address, size);
+ m_system.InvalidateCpuInstructionCacheRange(dst_address, size);
} else {
- system.InvalidateCpuInstructionCaches();
+ m_system.InvalidateCpuInstructionCaches();
}
}
});
@@ -406,7 +448,21 @@ Result KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::si
// Unmap.
{
// Determine the number of pages being operated on.
- const std::size_t num_pages = size / PageSize;
+ const size_t num_pages = size / PageSize;
+
+ // Create an update allocator for the source.
+ Result src_allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator src_allocator(std::addressof(src_allocator_result),
+ m_memory_block_slab_manager,
+ num_src_allocator_blocks);
+ R_TRY(src_allocator_result);
+
+ // Create an update allocator for the destination.
+ Result dst_allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator dst_allocator(std::addressof(dst_allocator_result),
+ m_memory_block_slab_manager,
+ num_dst_allocator_blocks);
+ R_TRY(dst_allocator_result);
// Unmap the aliased copy of the pages.
R_TRY(Operate(dst_address, num_pages, KMemoryPermission::None, OperationType::Unmap));
@@ -416,73 +472,34 @@ Result KPageTable::UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::si
OperationType::ChangePermissions));
// Apply the memory block updates.
- block_manager->Update(dst_address, num_pages, KMemoryState::None);
- block_manager->Update(src_address, num_pages, KMemoryState::Normal,
- KMemoryPermission::UserReadWrite);
+ m_memory_block_manager.Update(
+ std::addressof(dst_allocator), dst_address, num_pages, KMemoryState::None,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None, KMemoryBlockDisableMergeAttribute::Normal);
+ m_memory_block_manager.Update(
+ std::addressof(src_allocator), src_address, num_pages, KMemoryState::Normal,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None, KMemoryBlockDisableMergeAttribute::Locked);
// Note that we reprotected pages.
reprotected_pages = true;
}
- return ResultSuccess;
+ R_SUCCEED();
}
-VAddr KPageTable::FindFreeArea(VAddr region_start, std::size_t region_num_pages,
- std::size_t num_pages, std::size_t alignment, std::size_t offset,
- std::size_t guard_pages) {
+VAddr KPageTable::FindFreeArea(VAddr region_start, size_t region_num_pages, size_t num_pages,
+ size_t alignment, size_t offset, size_t guard_pages) {
VAddr address = 0;
if (num_pages <= region_num_pages) {
if (this->IsAslrEnabled()) {
- // Try to directly find a free area up to 8 times.
- for (std::size_t i = 0; i < 8; i++) {
- const std::size_t random_offset =
- KSystemControl::GenerateRandomRange(
- 0, (region_num_pages - num_pages - guard_pages) * PageSize / alignment) *
- alignment;
- const VAddr candidate =
- Common::AlignDown((region_start + random_offset), alignment) + offset;
-
- KMemoryInfo info = this->QueryInfoImpl(candidate);
-
- if (info.state != KMemoryState::Free) {
- continue;
- }
- if (region_start > candidate) {
- continue;
- }
- if (info.GetAddress() + guard_pages * PageSize > candidate) {
- continue;
- }
-
- const VAddr candidate_end = candidate + (num_pages + guard_pages) * PageSize - 1;
- if (candidate_end > info.GetLastAddress()) {
- continue;
- }
- if (candidate_end > region_start + region_num_pages * PageSize - 1) {
- continue;
- }
-
- address = candidate;
- break;
- }
- // Fall back to finding the first free area with a random offset.
- if (address == 0) {
- // NOTE: Nintendo does not account for guard pages here.
- // This may theoretically cause an offset to be chosen that cannot be mapped. We
- // will account for guard pages.
- const std::size_t offset_pages = KSystemControl::GenerateRandomRange(
- 0, region_num_pages - num_pages - guard_pages);
- address = block_manager->FindFreeArea(region_start + offset_pages * PageSize,
- region_num_pages - offset_pages, num_pages,
- alignment, offset, guard_pages);
- }
+ UNIMPLEMENTED();
}
-
// Find the first free area.
if (address == 0) {
- address = block_manager->FindFreeArea(region_start, region_num_pages, num_pages,
- alignment, offset, guard_pages);
+ address = m_memory_block_manager.FindFreeArea(region_start, region_num_pages, num_pages,
+ alignment, offset, guard_pages);
}
}
@@ -500,7 +517,8 @@ Result KPageTable::MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages) {
// Begin traversal.
Common::PageTable::TraversalContext context;
Common::PageTable::TraversalEntry next_entry;
- R_UNLESS(page_table_impl.BeginTraversal(next_entry, context, addr), ResultInvalidCurrentMemory);
+ R_UNLESS(m_page_table_impl->BeginTraversal(next_entry, context, addr),
+ ResultInvalidCurrentMemory);
// Prepare tracking variables.
PAddr cur_addr = next_entry.phys_addr;
@@ -508,9 +526,9 @@ Result KPageTable::MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages) {
size_t tot_size = cur_size;
// Iterate, adding to group as we go.
- const auto& memory_layout = system.Kernel().MemoryLayout();
+ const auto& memory_layout = m_system.Kernel().MemoryLayout();
while (tot_size < size) {
- R_UNLESS(page_table_impl.ContinueTraversal(next_entry, context),
+ R_UNLESS(m_page_table_impl->ContinueTraversal(next_entry, context),
ResultInvalidCurrentMemory);
if (next_entry.phys_addr != (cur_addr + cur_size)) {
@@ -538,7 +556,7 @@ Result KPageTable::MakePageGroup(KPageGroup& pg, VAddr addr, size_t num_pages) {
R_UNLESS(IsHeapPhysicalAddress(memory_layout, cur_addr), ResultInvalidCurrentMemory);
R_TRY(pg.AddBlock(cur_addr, cur_pages));
- return ResultSuccess;
+ R_SUCCEED();
}
bool KPageTable::IsValidPageGroup(const KPageGroup& pg_ll, VAddr addr, size_t num_pages) {
@@ -546,7 +564,7 @@ bool KPageTable::IsValidPageGroup(const KPageGroup& pg_ll, VAddr addr, size_t nu
const size_t size = num_pages * PageSize;
const auto& pg = pg_ll.Nodes();
- const auto& memory_layout = system.Kernel().MemoryLayout();
+ const auto& memory_layout = m_system.Kernel().MemoryLayout();
// Empty groups are necessarily invalid.
if (pg.empty()) {
@@ -573,7 +591,7 @@ bool KPageTable::IsValidPageGroup(const KPageGroup& pg_ll, VAddr addr, size_t nu
// Begin traversal.
Common::PageTable::TraversalContext context;
Common::PageTable::TraversalEntry next_entry;
- if (!page_table_impl.BeginTraversal(next_entry, context, addr)) {
+ if (!m_page_table_impl->BeginTraversal(next_entry, context, addr)) {
return false;
}
@@ -584,7 +602,7 @@ bool KPageTable::IsValidPageGroup(const KPageGroup& pg_ll, VAddr addr, size_t nu
// Iterate, comparing expected to actual.
while (tot_size < size) {
- if (!page_table_impl.ContinueTraversal(next_entry, context)) {
+ if (!m_page_table_impl->ContinueTraversal(next_entry, context)) {
return false;
}
@@ -630,11 +648,11 @@ bool KPageTable::IsValidPageGroup(const KPageGroup& pg_ll, VAddr addr, size_t nu
return cur_block_address == cur_addr && cur_block_pages == (cur_size / PageSize);
}
-Result KPageTable::UnmapProcessMemory(VAddr dst_addr, std::size_t size, KPageTable& src_page_table,
+Result KPageTable::UnmapProcessMemory(VAddr dst_addr, size_t size, KPageTable& src_page_table,
VAddr src_addr) {
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
- const std::size_t num_pages{size / PageSize};
+ const size_t num_pages{size / PageSize};
// Check that the memory is mapped in the destination process.
size_t num_allocator_blocks;
@@ -649,43 +667,51 @@ Result KPageTable::UnmapProcessMemory(VAddr dst_addr, std::size_t size, KPageTab
KMemoryPermission::None, KMemoryAttribute::All,
KMemoryAttribute::None));
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
CASCADE_CODE(Operate(dst_addr, num_pages, KMemoryPermission::None, OperationType::Unmap));
// Apply the memory block update.
- block_manager->Update(dst_addr, num_pages, KMemoryState::Free, KMemoryPermission::None,
- KMemoryAttribute::None);
+ m_memory_block_manager.Update(std::addressof(allocator), dst_addr, num_pages,
+ KMemoryState::Free, KMemoryPermission::None,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal);
- system.InvalidateCpuInstructionCaches();
+ m_system.InvalidateCpuInstructionCaches();
- return ResultSuccess;
+ R_SUCCEED();
}
-Result KPageTable::MapPhysicalMemory(VAddr address, std::size_t size) {
+Result KPageTable::MapPhysicalMemory(VAddr address, size_t size) {
// Lock the physical memory lock.
- KScopedLightLock map_phys_mem_lk(map_physical_memory_lock);
+ KScopedLightLock map_phys_mem_lk(m_map_physical_memory_lock);
// Calculate the last address for convenience.
const VAddr last_address = address + size - 1;
// Define iteration variables.
VAddr cur_address;
- std::size_t mapped_size;
+ size_t mapped_size;
// The entire mapping process can be retried.
while (true) {
// Check if the memory is already mapped.
{
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Iterate over the memory.
cur_address = address;
mapped_size = 0;
- auto it = block_manager->FindIterator(cur_address);
+ auto it = m_memory_block_manager.FindIterator(cur_address);
while (true) {
// Check that the iterator is valid.
- ASSERT(it != block_manager->end());
+ ASSERT(it != m_memory_block_manager.end());
// Get the memory info.
const KMemoryInfo info = it->GetMemoryInfo();
@@ -716,20 +742,20 @@ Result KPageTable::MapPhysicalMemory(VAddr address, std::size_t size) {
{
// Reserve the memory from the process resource limit.
KScopedResourceReservation memory_reservation(
- system.Kernel().CurrentProcess()->GetResourceLimit(),
+ m_system.Kernel().CurrentProcess()->GetResourceLimit(),
LimitableResource::PhysicalMemory, size - mapped_size);
R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
// Allocate pages for the new memory.
KPageGroup pg;
- R_TRY(system.Kernel().MemoryManager().AllocateAndOpenForProcess(
+ R_TRY(m_system.Kernel().MemoryManager().AllocateAndOpenForProcess(
&pg, (size - mapped_size) / PageSize,
- KMemoryManager::EncodeOption(memory_pool, allocation_option), 0, 0));
+ KMemoryManager::EncodeOption(m_memory_pool, m_allocation_option), 0, 0));
// Map the memory.
{
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
size_t num_allocator_blocks = 0;
@@ -739,10 +765,10 @@ Result KPageTable::MapPhysicalMemory(VAddr address, std::size_t size) {
size_t checked_mapped_size = 0;
cur_address = address;
- auto it = block_manager->FindIterator(cur_address);
+ auto it = m_memory_block_manager.FindIterator(cur_address);
while (true) {
// Check that the iterator is valid.
- ASSERT(it != block_manager->end());
+ ASSERT(it != m_memory_block_manager.end());
// Get the memory info.
const KMemoryInfo info = it->GetMemoryInfo();
@@ -782,6 +808,14 @@ Result KPageTable::MapPhysicalMemory(VAddr address, std::size_t size) {
}
}
+ // Create an update allocator.
+ ASSERT(num_allocator_blocks <= KMemoryBlockManagerUpdateAllocator::MaxBlocks);
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager,
+ num_allocator_blocks);
+ R_TRY(allocator_result);
+
// Reset the current tracking address, and make sure we clean up on failure.
cur_address = address;
auto unmap_guard = detail::ScopeExit([&] {
@@ -791,10 +825,10 @@ Result KPageTable::MapPhysicalMemory(VAddr address, std::size_t size) {
// Iterate, unmapping the pages.
cur_address = address;
- auto it = block_manager->FindIterator(cur_address);
+ auto it = m_memory_block_manager.FindIterator(cur_address);
while (true) {
// Check that the iterator is valid.
- ASSERT(it != block_manager->end());
+ ASSERT(it != m_memory_block_manager.end());
// Get the memory info.
const KMemoryInfo info = it->GetMemoryInfo();
@@ -830,10 +864,10 @@ Result KPageTable::MapPhysicalMemory(VAddr address, std::size_t size) {
PAddr pg_phys_addr = pg_it->GetAddress();
size_t pg_pages = pg_it->GetNumPages();
- auto it = block_manager->FindIterator(cur_address);
+ auto it = m_memory_block_manager.FindIterator(cur_address);
while (true) {
// Check that the iterator is valid.
- ASSERT(it != block_manager->end());
+ ASSERT(it != m_memory_block_manager.end());
// Get the memory info.
const KMemoryInfo info = it->GetMemoryInfo();
@@ -886,37 +920,37 @@ Result KPageTable::MapPhysicalMemory(VAddr address, std::size_t size) {
memory_reservation.Commit();
// Increase our tracked mapped size.
- mapped_physical_memory_size += (size - mapped_size);
+ m_mapped_physical_memory_size += (size - mapped_size);
// Update the relevant memory blocks.
- block_manager->Update(address, size / PageSize, KMemoryState::Free,
- KMemoryPermission::None, KMemoryAttribute::None,
- KMemoryState::Normal, KMemoryPermission::UserReadWrite,
- KMemoryAttribute::None);
+ m_memory_block_manager.UpdateIfMatch(
+ std::addressof(allocator), address, size / PageSize, KMemoryState::Free,
+ KMemoryPermission::None, KMemoryAttribute::None, KMemoryState::Normal,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::None);
// Cancel our guard.
unmap_guard.Cancel();
- return ResultSuccess;
+ R_SUCCEED();
}
}
}
}
-Result KPageTable::UnmapPhysicalMemory(VAddr address, std::size_t size) {
+Result KPageTable::UnmapPhysicalMemory(VAddr address, size_t size) {
// Lock the physical memory lock.
- KScopedLightLock map_phys_mem_lk(map_physical_memory_lock);
+ KScopedLightLock map_phys_mem_lk(m_map_physical_memory_lock);
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Calculate the last address for convenience.
const VAddr last_address = address + size - 1;
// Define iteration variables.
VAddr cur_address = 0;
- std::size_t mapped_size = 0;
- std::size_t num_allocator_blocks = 0;
+ size_t mapped_size = 0;
+ size_t num_allocator_blocks = 0;
// Check if the memory is mapped.
{
@@ -924,10 +958,10 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, std::size_t size) {
cur_address = address;
mapped_size = 0;
- auto it = block_manager->FindIterator(cur_address);
+ auto it = m_memory_block_manager.FindIterator(cur_address);
while (true) {
// Check that the iterator is valid.
- ASSERT(it != block_manager->end());
+ ASSERT(it != m_memory_block_manager.end());
// Get the memory info.
const KMemoryInfo info = it->GetMemoryInfo();
@@ -1022,6 +1056,13 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, std::size_t size) {
}
ASSERT(pg.GetNumPages() == mapped_size / PageSize);
+ // Create an update allocator.
+ ASSERT(num_allocator_blocks <= KMemoryBlockManagerUpdateAllocator::MaxBlocks);
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
// Reset the current tracking address, and make sure we clean up on failure.
cur_address = address;
auto remap_guard = detail::ScopeExit([&] {
@@ -1030,7 +1071,7 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, std::size_t size) {
cur_address = address;
// Iterate over the memory we unmapped.
- auto it = block_manager->FindIterator(cur_address);
+ auto it = m_memory_block_manager.FindIterator(cur_address);
auto pg_it = pg.Nodes().begin();
PAddr pg_phys_addr = pg_it->GetAddress();
size_t pg_pages = pg_it->GetNumPages();
@@ -1085,10 +1126,10 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, std::size_t size) {
});
// Iterate over the memory, unmapping as we go.
- auto it = block_manager->FindIterator(cur_address);
+ auto it = m_memory_block_manager.FindIterator(cur_address);
while (true) {
// Check that the iterator is valid.
- ASSERT(it != block_manager->end());
+ ASSERT(it != m_memory_block_manager.end());
// Get the memory info.
const KMemoryInfo info = it->GetMemoryInfo();
@@ -1115,104 +1156,159 @@ Result KPageTable::UnmapPhysicalMemory(VAddr address, std::size_t size) {
}
// Release the memory resource.
- mapped_physical_memory_size -= mapped_size;
- auto process{system.Kernel().CurrentProcess()};
+ m_mapped_physical_memory_size -= mapped_size;
+ auto process{m_system.Kernel().CurrentProcess()};
process->GetResourceLimit()->Release(LimitableResource::PhysicalMemory, mapped_size);
// Update memory blocks.
- block_manager->Update(address, size / PageSize, KMemoryState::Free, KMemoryPermission::None,
- KMemoryAttribute::None);
+ m_memory_block_manager.Update(std::addressof(allocator), address, size / PageSize,
+ KMemoryState::Free, KMemoryPermission::None,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None);
// TODO(bunnei): This is a workaround until the next set of changes, where we add reference
// counting for mapped pages. Until then, we must manually close the reference to the page
// group.
- system.Kernel().MemoryManager().Close(pg);
+ m_system.Kernel().MemoryManager().Close(pg);
// We succeeded.
remap_guard.Cancel();
- return ResultSuccess;
+ R_SUCCEED();
}
-Result KPageTable::MapMemory(VAddr dst_addr, VAddr src_addr, std::size_t size) {
- KScopedLightLock lk(general_lock);
-
- KMemoryState src_state{};
- CASCADE_CODE(CheckMemoryState(
- &src_state, nullptr, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias,
- KMemoryState::FlagCanAlias, KMemoryPermission::All, KMemoryPermission::UserReadWrite,
- KMemoryAttribute::Mask, KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped));
+Result KPageTable::MapMemory(VAddr dst_address, VAddr src_address, size_t size) {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Validate that the source address's state is valid.
+ KMemoryState src_state;
+ size_t num_src_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(src_state), nullptr, nullptr,
+ std::addressof(num_src_allocator_blocks), src_address, size,
+ KMemoryState::FlagCanAlias, KMemoryState::FlagCanAlias,
+ KMemoryPermission::All, KMemoryPermission::UserReadWrite,
+ KMemoryAttribute::All, KMemoryAttribute::None));
- if (IsRegionMapped(dst_addr, size)) {
- return ResultInvalidCurrentMemory;
- }
+ // Validate that the dst address's state is valid.
+ size_t num_dst_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_dst_allocator_blocks), dst_address, size,
+ KMemoryState::All, KMemoryState::Free, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryAttribute::None));
+ // Create an update allocator for the source.
+ Result src_allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator src_allocator(std::addressof(src_allocator_result),
+ m_memory_block_slab_manager,
+ num_src_allocator_blocks);
+ R_TRY(src_allocator_result);
+
+ // Create an update allocator for the destination.
+ Result dst_allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator dst_allocator(std::addressof(dst_allocator_result),
+ m_memory_block_slab_manager,
+ num_dst_allocator_blocks);
+ R_TRY(dst_allocator_result);
+
+ // Map the memory.
KPageGroup page_linked_list;
- const std::size_t num_pages{size / PageSize};
-
- AddRegionToPages(src_addr, num_pages, page_linked_list);
+ const size_t num_pages{size / PageSize};
+ const KMemoryPermission new_src_perm = static_cast<KMemoryPermission>(
+ KMemoryPermission::KernelRead | KMemoryPermission::NotMapped);
+ const KMemoryAttribute new_src_attr = KMemoryAttribute::Locked;
+ AddRegionToPages(src_address, num_pages, page_linked_list);
{
+ // Reprotect the source as kernel-read/not mapped.
auto block_guard = detail::ScopeExit([&] {
- Operate(src_addr, num_pages, KMemoryPermission::UserReadWrite,
+ Operate(src_address, num_pages, KMemoryPermission::UserReadWrite,
OperationType::ChangePermissions);
});
-
- CASCADE_CODE(Operate(src_addr, num_pages, KMemoryPermission::None,
- OperationType::ChangePermissions));
- CASCADE_CODE(MapPages(dst_addr, page_linked_list, KMemoryPermission::UserReadWrite));
+ R_TRY(Operate(src_address, num_pages, new_src_perm, OperationType::ChangePermissions));
+ R_TRY(MapPages(dst_address, page_linked_list, KMemoryPermission::UserReadWrite));
block_guard.Cancel();
}
- block_manager->Update(src_addr, num_pages, src_state, KMemoryPermission::None,
- KMemoryAttribute::Locked);
- block_manager->Update(dst_addr, num_pages, KMemoryState::Stack,
- KMemoryPermission::UserReadWrite);
-
- return ResultSuccess;
+ // Apply the memory block updates.
+ m_memory_block_manager.Update(std::addressof(src_allocator), src_address, num_pages, src_state,
+ new_src_perm, new_src_attr,
+ KMemoryBlockDisableMergeAttribute::Locked,
+ KMemoryBlockDisableMergeAttribute::None);
+ m_memory_block_manager.Update(std::addressof(dst_allocator), dst_address, num_pages,
+ KMemoryState::Stack, KMemoryPermission::UserReadWrite,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
+
+ R_SUCCEED();
}
-Result KPageTable::UnmapMemory(VAddr dst_addr, VAddr src_addr, std::size_t size) {
- KScopedLightLock lk(general_lock);
+Result KPageTable::UnmapMemory(VAddr dst_address, VAddr src_address, size_t size) {
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Validate that the source address's state is valid.
+ KMemoryState src_state;
+ size_t num_src_allocator_blocks;
+ R_TRY(this->CheckMemoryState(
+ std::addressof(src_state), nullptr, nullptr, std::addressof(num_src_allocator_blocks),
+ src_address, size, KMemoryState::FlagCanAlias, KMemoryState::FlagCanAlias,
+ KMemoryPermission::All, KMemoryPermission::NotMapped | KMemoryPermission::KernelRead,
+ KMemoryAttribute::All, KMemoryAttribute::Locked));
+
+ // Validate that the dst address's state is valid.
+ KMemoryPermission dst_perm;
+ size_t num_dst_allocator_blocks;
+ R_TRY(this->CheckMemoryState(
+ nullptr, std::addressof(dst_perm), nullptr, std::addressof(num_dst_allocator_blocks),
+ dst_address, size, KMemoryState::All, KMemoryState::Stack, KMemoryPermission::None,
+ KMemoryPermission::None, KMemoryAttribute::All, KMemoryAttribute::None));
- KMemoryState src_state{};
- CASCADE_CODE(CheckMemoryState(
- &src_state, nullptr, nullptr, nullptr, src_addr, size, KMemoryState::FlagCanAlias,
- KMemoryState::FlagCanAlias, KMemoryPermission::All, KMemoryPermission::None,
- KMemoryAttribute::Mask, KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped));
+ // Create an update allocator for the source.
+ Result src_allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator src_allocator(std::addressof(src_allocator_result),
+ m_memory_block_slab_manager,
+ num_src_allocator_blocks);
+ R_TRY(src_allocator_result);
- KMemoryPermission dst_perm{};
- CASCADE_CODE(CheckMemoryState(nullptr, &dst_perm, nullptr, nullptr, dst_addr, size,
- KMemoryState::All, KMemoryState::Stack, KMemoryPermission::None,
- KMemoryPermission::None, KMemoryAttribute::Mask,
- KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped));
+ // Create an update allocator for the destination.
+ Result dst_allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator dst_allocator(std::addressof(dst_allocator_result),
+ m_memory_block_slab_manager,
+ num_dst_allocator_blocks);
+ R_TRY(dst_allocator_result);
KPageGroup src_pages;
KPageGroup dst_pages;
- const std::size_t num_pages{size / PageSize};
+ const size_t num_pages{size / PageSize};
- AddRegionToPages(src_addr, num_pages, src_pages);
- AddRegionToPages(dst_addr, num_pages, dst_pages);
+ AddRegionToPages(src_address, num_pages, src_pages);
+ AddRegionToPages(dst_address, num_pages, dst_pages);
- if (!dst_pages.IsEqual(src_pages)) {
- return ResultInvalidMemoryRegion;
- }
+ R_UNLESS(dst_pages.IsEqual(src_pages), ResultInvalidMemoryRegion);
{
- auto block_guard = detail::ScopeExit([&] { MapPages(dst_addr, dst_pages, dst_perm); });
+ auto block_guard = detail::ScopeExit([&] { MapPages(dst_address, dst_pages, dst_perm); });
- CASCADE_CODE(Operate(dst_addr, num_pages, KMemoryPermission::None, OperationType::Unmap));
- CASCADE_CODE(Operate(src_addr, num_pages, KMemoryPermission::UserReadWrite,
- OperationType::ChangePermissions));
+ R_TRY(Operate(dst_address, num_pages, KMemoryPermission::None, OperationType::Unmap));
+ R_TRY(Operate(src_address, num_pages, KMemoryPermission::UserReadWrite,
+ OperationType::ChangePermissions));
block_guard.Cancel();
}
- block_manager->Update(src_addr, num_pages, src_state, KMemoryPermission::UserReadWrite);
- block_manager->Update(dst_addr, num_pages, KMemoryState::Free);
-
- return ResultSuccess;
+ // Apply the memory block updates.
+ m_memory_block_manager.Update(std::addressof(src_allocator), src_address, num_pages, src_state,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Locked);
+ m_memory_block_manager.Update(std::addressof(dst_allocator), dst_address, num_pages,
+ KMemoryState::None, KMemoryPermission::None,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal);
+
+ R_SUCCEED();
}
Result KPageTable::MapPages(VAddr addr, const KPageGroup& page_linked_list,
@@ -1225,48 +1321,54 @@ Result KPageTable::MapPages(VAddr addr, const KPageGroup& page_linked_list,
if (const auto result{
Operate(cur_addr, node.GetNumPages(), perm, OperationType::Map, node.GetAddress())};
result.IsError()) {
- const std::size_t num_pages{(addr - cur_addr) / PageSize};
+ const size_t num_pages{(addr - cur_addr) / PageSize};
ASSERT(Operate(addr, num_pages, KMemoryPermission::None, OperationType::Unmap)
.IsSuccess());
- return result;
+ R_RETURN(result);
}
cur_addr += node.GetNumPages() * PageSize;
}
- return ResultSuccess;
+ R_SUCCEED();
}
Result KPageTable::MapPages(VAddr address, KPageGroup& page_linked_list, KMemoryState state,
KMemoryPermission perm) {
// Check that the map is in range.
- const std::size_t num_pages{page_linked_list.GetNumPages()};
- const std::size_t size{num_pages * PageSize};
+ const size_t num_pages{page_linked_list.GetNumPages()};
+ const size_t size{num_pages * PageSize};
R_UNLESS(this->CanContain(address, size, state), ResultInvalidCurrentMemory);
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Check the memory state.
R_TRY(this->CheckMemoryState(address, size, KMemoryState::All, KMemoryState::Free,
KMemoryPermission::None, KMemoryPermission::None,
KMemoryAttribute::None, KMemoryAttribute::None));
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager);
+
// Map the pages.
R_TRY(MapPages(address, page_linked_list, perm));
// Update the blocks.
- block_manager->Update(address, num_pages, state, perm);
+ m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, state, perm,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
- return ResultSuccess;
+ R_SUCCEED();
}
-Result KPageTable::MapPages(VAddr* out_addr, std::size_t num_pages, std::size_t alignment,
- PAddr phys_addr, bool is_pa_valid, VAddr region_start,
- std::size_t region_num_pages, KMemoryState state,
- KMemoryPermission perm) {
+Result KPageTable::MapPages(VAddr* out_addr, size_t num_pages, size_t alignment, PAddr phys_addr,
+ bool is_pa_valid, VAddr region_start, size_t region_num_pages,
+ KMemoryState state, KMemoryPermission perm) {
ASSERT(Common::IsAligned(alignment, PageSize) && alignment >= PageSize);
// Ensure this is a valid map request.
@@ -1275,7 +1377,7 @@ Result KPageTable::MapPages(VAddr* out_addr, std::size_t num_pages, std::size_t
R_UNLESS(num_pages < region_num_pages, ResultOutOfMemory);
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Find a random address to map at.
VAddr addr = this->FindFreeArea(region_start, region_num_pages, num_pages, alignment, 0,
@@ -1288,6 +1390,11 @@ Result KPageTable::MapPages(VAddr* out_addr, std::size_t num_pages, std::size_t
KMemoryAttribute::None, KMemoryAttribute::None)
.IsSuccess());
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager);
+
// Perform mapping operation.
if (is_pa_valid) {
R_TRY(this->Operate(addr, num_pages, perm, OperationType::Map, phys_addr));
@@ -1296,11 +1403,13 @@ Result KPageTable::MapPages(VAddr* out_addr, std::size_t num_pages, std::size_t
}
// Update the blocks.
- block_manager->Update(addr, num_pages, state, perm);
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, state, perm,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
// We successfully mapped the pages.
*out_addr = addr;
- return ResultSuccess;
+ R_SUCCEED();
}
Result KPageTable::UnmapPages(VAddr addr, const KPageGroup& page_linked_list) {
@@ -1312,60 +1421,80 @@ Result KPageTable::UnmapPages(VAddr addr, const KPageGroup& page_linked_list) {
if (const auto result{Operate(cur_addr, node.GetNumPages(), KMemoryPermission::None,
OperationType::Unmap)};
result.IsError()) {
- return result;
+ R_RETURN(result);
}
cur_addr += node.GetNumPages() * PageSize;
}
- return ResultSuccess;
+ R_SUCCEED();
}
-Result KPageTable::UnmapPages(VAddr addr, KPageGroup& page_linked_list, KMemoryState state) {
+Result KPageTable::UnmapPages(VAddr address, KPageGroup& page_linked_list, KMemoryState state) {
// Check that the unmap is in range.
- const std::size_t num_pages{page_linked_list.GetNumPages()};
- const std::size_t size{num_pages * PageSize};
- R_UNLESS(this->Contains(addr, size), ResultInvalidCurrentMemory);
+ const size_t num_pages{page_linked_list.GetNumPages()};
+ const size_t size{num_pages * PageSize};
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Check the memory state.
- R_TRY(this->CheckMemoryState(addr, size, KMemoryState::All, state, KMemoryPermission::None,
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size,
+ KMemoryState::All, state, KMemoryPermission::None,
KMemoryPermission::None, KMemoryAttribute::All,
KMemoryAttribute::None));
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
// Perform the unmap.
- R_TRY(UnmapPages(addr, page_linked_list));
+ R_TRY(UnmapPages(address, page_linked_list));
// Update the blocks.
- block_manager->Update(addr, num_pages, state, KMemoryPermission::None);
+ m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, KMemoryState::Free,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal);
- return ResultSuccess;
+ R_SUCCEED();
}
-Result KPageTable::UnmapPages(VAddr address, std::size_t num_pages, KMemoryState state) {
+Result KPageTable::UnmapPages(VAddr address, size_t num_pages, KMemoryState state) {
// Check that the unmap is in range.
- const std::size_t size = num_pages * PageSize;
+ const size_t size = num_pages * PageSize;
R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Check the memory state.
- std::size_t num_allocator_blocks{};
+ size_t num_allocator_blocks{};
R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size,
KMemoryState::All, state, KMemoryPermission::None,
KMemoryPermission::None, KMemoryAttribute::All,
KMemoryAttribute::None));
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
// Perform the unmap.
R_TRY(Operate(address, num_pages, KMemoryPermission::None, OperationType::Unmap));
// Update the blocks.
- block_manager->Update(address, num_pages, KMemoryState::Free, KMemoryPermission::None);
+ m_memory_block_manager.Update(std::addressof(allocator), address, num_pages, KMemoryState::Free,
+ KMemoryPermission::None, KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Normal);
- return ResultSuccess;
+ R_SUCCEED();
}
Result KPageTable::MakeAndOpenPageGroup(KPageGroup* out, VAddr address, size_t num_pages,
@@ -1380,7 +1509,7 @@ Result KPageTable::MakeAndOpenPageGroup(KPageGroup* out, VAddr address, size_t n
R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Check if state allows us to create the group.
R_TRY(this->CheckMemoryState(address, size, state_mask | KMemoryState::FlagReferenceCounted,
@@ -1390,15 +1519,15 @@ Result KPageTable::MakeAndOpenPageGroup(KPageGroup* out, VAddr address, size_t n
// Create a new page group for the region.
R_TRY(this->MakePageGroup(*out, address, num_pages));
- return ResultSuccess;
+ R_SUCCEED();
}
-Result KPageTable::SetProcessMemoryPermission(VAddr addr, std::size_t size,
+Result KPageTable::SetProcessMemoryPermission(VAddr addr, size_t size,
Svc::MemoryPermission svc_perm) {
const size_t num_pages = size / PageSize;
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Verify we can change the memory permission.
KMemoryState old_state;
@@ -1435,105 +1564,101 @@ Result KPageTable::SetProcessMemoryPermission(VAddr addr, std::size_t size,
// Succeed if there's nothing to do.
R_SUCCEED_IF(old_perm == new_perm && old_state == new_state);
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
// Perform mapping operation.
const auto operation =
was_x ? OperationType::ChangePermissionsAndRefresh : OperationType::ChangePermissions;
R_TRY(Operate(addr, num_pages, new_perm, operation));
// Update the blocks.
- block_manager->Update(addr, num_pages, new_state, new_perm, KMemoryAttribute::None);
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, new_state, new_perm,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None);
// Ensure cache coherency, if we're setting pages as executable.
if (is_x) {
- system.InvalidateCpuInstructionCacheRange(addr, size);
+ m_system.InvalidateCpuInstructionCacheRange(addr, size);
}
- return ResultSuccess;
+ R_SUCCEED();
}
KMemoryInfo KPageTable::QueryInfoImpl(VAddr addr) {
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
- return block_manager->FindBlock(addr).GetMemoryInfo();
+ return m_memory_block_manager.FindBlock(addr)->GetMemoryInfo();
}
KMemoryInfo KPageTable::QueryInfo(VAddr addr) {
if (!Contains(addr, 1)) {
- return {address_space_end, 0 - address_space_end, KMemoryState::Inaccessible,
- KMemoryPermission::None, KMemoryAttribute::None, KMemoryPermission::None};
+ return {
+ .m_address = m_address_space_end,
+ .m_size = 0 - m_address_space_end,
+ .m_state = static_cast<KMemoryState>(Svc::MemoryState::Inaccessible),
+ .m_device_disable_merge_left_count = 0,
+ .m_device_disable_merge_right_count = 0,
+ .m_ipc_lock_count = 0,
+ .m_device_use_count = 0,
+ .m_ipc_disable_merge_count = 0,
+ .m_permission = KMemoryPermission::None,
+ .m_attribute = KMemoryAttribute::None,
+ .m_original_permission = KMemoryPermission::None,
+ .m_disable_merge_attribute = KMemoryBlockDisableMergeAttribute::None,
+ };
}
return QueryInfoImpl(addr);
}
-Result KPageTable::ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm) {
- KScopedLightLock lk(general_lock);
-
- KMemoryState state{};
- KMemoryAttribute attribute{};
-
- R_TRY(CheckMemoryState(&state, nullptr, &attribute, nullptr, addr, size,
- KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted,
- KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted,
- KMemoryPermission::All, KMemoryPermission::UserReadWrite,
- KMemoryAttribute::Mask, KMemoryAttribute::None,
- KMemoryAttribute::IpcAndDeviceMapped));
-
- block_manager->Update(addr, size / PageSize, state, perm, attribute | KMemoryAttribute::Locked);
-
- return ResultSuccess;
-}
-
-Result KPageTable::ResetTransferMemory(VAddr addr, std::size_t size) {
- KScopedLightLock lk(general_lock);
-
- KMemoryState state{};
-
- R_TRY(CheckMemoryState(&state, nullptr, nullptr, nullptr, addr, size,
- KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted,
- KMemoryState::FlagCanTransfer | KMemoryState::FlagReferenceCounted,
- KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::Mask,
- KMemoryAttribute::Locked, KMemoryAttribute::IpcAndDeviceMapped));
-
- block_manager->Update(addr, size / PageSize, state, KMemoryPermission::UserReadWrite);
- return ResultSuccess;
-}
-
-Result KPageTable::SetMemoryPermission(VAddr addr, std::size_t size,
- Svc::MemoryPermission svc_perm) {
+Result KPageTable::SetMemoryPermission(VAddr addr, size_t size, Svc::MemoryPermission svc_perm) {
const size_t num_pages = size / PageSize;
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Verify we can change the memory permission.
KMemoryState old_state;
KMemoryPermission old_perm;
- R_TRY(this->CheckMemoryState(
- std::addressof(old_state), std::addressof(old_perm), nullptr, nullptr, addr, size,
- KMemoryState::FlagCanReprotect, KMemoryState::FlagCanReprotect, KMemoryPermission::None,
- KMemoryPermission::None, KMemoryAttribute::All, KMemoryAttribute::None));
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(old_state), std::addressof(old_perm), nullptr,
+ std::addressof(num_allocator_blocks), addr, size,
+ KMemoryState::FlagCanReprotect, KMemoryState::FlagCanReprotect,
+ KMemoryPermission::None, KMemoryPermission::None,
+ KMemoryAttribute::All, KMemoryAttribute::None));
// Determine new perm.
const KMemoryPermission new_perm = ConvertToKMemoryPermission(svc_perm);
R_SUCCEED_IF(old_perm == new_perm);
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
// Perform mapping operation.
R_TRY(Operate(addr, num_pages, new_perm, OperationType::ChangePermissions));
// Update the blocks.
- block_manager->Update(addr, num_pages, old_state, new_perm, KMemoryAttribute::None);
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, new_perm,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None);
- return ResultSuccess;
+ R_SUCCEED();
}
-Result KPageTable::SetMemoryAttribute(VAddr addr, std::size_t size, u32 mask, u32 attr) {
+Result KPageTable::SetMemoryAttribute(VAddr addr, size_t size, u32 mask, u32 attr) {
const size_t num_pages = size / PageSize;
ASSERT((static_cast<KMemoryAttribute>(mask) | KMemoryAttribute::SetMask) ==
KMemoryAttribute::SetMask);
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Verify we can change the memory attribute.
KMemoryState old_state;
@@ -1548,6 +1673,12 @@ Result KPageTable::SetMemoryAttribute(VAddr addr, std::size_t size, u32 mask, u3
KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None,
AttributeTestMask, KMemoryAttribute::None, ~AttributeTestMask));
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
// Determine the new attribute.
const KMemoryAttribute new_attr =
static_cast<KMemoryAttribute>(((old_attr & static_cast<KMemoryAttribute>(~mask)) |
@@ -1557,123 +1688,142 @@ Result KPageTable::SetMemoryAttribute(VAddr addr, std::size_t size, u32 mask, u3
this->Operate(addr, num_pages, old_perm, OperationType::ChangePermissionsAndRefresh);
// Update the blocks.
- block_manager->Update(addr, num_pages, old_state, old_perm, new_attr);
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, old_perm,
+ new_attr, KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None);
- return ResultSuccess;
+ R_SUCCEED();
}
-Result KPageTable::SetMaxHeapSize(std::size_t size) {
+Result KPageTable::SetMaxHeapSize(size_t size) {
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Only process page tables are allowed to set heap size.
ASSERT(!this->IsKernel());
- max_heap_size = size;
+ m_max_heap_size = size;
- return ResultSuccess;
+ R_SUCCEED();
}
-Result KPageTable::SetHeapSize(VAddr* out, std::size_t size) {
+Result KPageTable::SetHeapSize(VAddr* out, size_t size) {
// Lock the physical memory mutex.
- KScopedLightLock map_phys_mem_lk(map_physical_memory_lock);
+ KScopedLightLock map_phys_mem_lk(m_map_physical_memory_lock);
// Try to perform a reduction in heap, instead of an extension.
VAddr cur_address{};
- std::size_t allocation_size{};
+ size_t allocation_size{};
{
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Validate that setting heap size is possible at all.
- R_UNLESS(!is_kernel, ResultOutOfMemory);
- R_UNLESS(size <= static_cast<std::size_t>(heap_region_end - heap_region_start),
+ R_UNLESS(!m_is_kernel, ResultOutOfMemory);
+ R_UNLESS(size <= static_cast<size_t>(m_heap_region_end - m_heap_region_start),
ResultOutOfMemory);
- R_UNLESS(size <= max_heap_size, ResultOutOfMemory);
+ R_UNLESS(size <= m_max_heap_size, ResultOutOfMemory);
if (size < GetHeapSize()) {
// The size being requested is less than the current size, so we need to free the end of
// the heap.
// Validate memory state.
- std::size_t num_allocator_blocks;
+ size_t num_allocator_blocks;
R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks),
- heap_region_start + size, GetHeapSize() - size,
+ m_heap_region_start + size, GetHeapSize() - size,
KMemoryState::All, KMemoryState::Normal,
KMemoryPermission::All, KMemoryPermission::UserReadWrite,
KMemoryAttribute::All, KMemoryAttribute::None));
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager,
+ num_allocator_blocks);
+ R_TRY(allocator_result);
+
// Unmap the end of the heap.
const auto num_pages = (GetHeapSize() - size) / PageSize;
- R_TRY(Operate(heap_region_start + size, num_pages, KMemoryPermission::None,
+ R_TRY(Operate(m_heap_region_start + size, num_pages, KMemoryPermission::None,
OperationType::Unmap));
// Release the memory from the resource limit.
- system.Kernel().CurrentProcess()->GetResourceLimit()->Release(
+ m_system.Kernel().CurrentProcess()->GetResourceLimit()->Release(
LimitableResource::PhysicalMemory, num_pages * PageSize);
// Apply the memory block update.
- block_manager->Update(heap_region_start + size, num_pages, KMemoryState::Free,
- KMemoryPermission::None, KMemoryAttribute::None);
+ m_memory_block_manager.Update(std::addressof(allocator), m_heap_region_start + size,
+ num_pages, KMemoryState::Free, KMemoryPermission::None,
+ KMemoryAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None,
+ size == 0 ? KMemoryBlockDisableMergeAttribute::Normal
+ : KMemoryBlockDisableMergeAttribute::None);
// Update the current heap end.
- current_heap_end = heap_region_start + size;
+ m_current_heap_end = m_heap_region_start + size;
// Set the output.
- *out = heap_region_start;
- return ResultSuccess;
+ *out = m_heap_region_start;
+ R_SUCCEED();
} else if (size == GetHeapSize()) {
// The size requested is exactly the current size.
- *out = heap_region_start;
- return ResultSuccess;
+ *out = m_heap_region_start;
+ R_SUCCEED();
} else {
// We have to allocate memory. Determine how much to allocate and where while the table
// is locked.
- cur_address = current_heap_end;
+ cur_address = m_current_heap_end;
allocation_size = size - GetHeapSize();
}
}
// Reserve memory for the heap extension.
KScopedResourceReservation memory_reservation(
- system.Kernel().CurrentProcess()->GetResourceLimit(), LimitableResource::PhysicalMemory,
+ m_system.Kernel().CurrentProcess()->GetResourceLimit(), LimitableResource::PhysicalMemory,
allocation_size);
R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached);
// Allocate pages for the heap extension.
KPageGroup pg;
- R_TRY(system.Kernel().MemoryManager().AllocateAndOpen(
+ R_TRY(m_system.Kernel().MemoryManager().AllocateAndOpen(
&pg, allocation_size / PageSize,
- KMemoryManager::EncodeOption(memory_pool, allocation_option)));
+ KMemoryManager::EncodeOption(m_memory_pool, m_allocation_option)));
// Clear all the newly allocated pages.
for (const auto& it : pg.Nodes()) {
- std::memset(system.DeviceMemory().GetPointer(it.GetAddress()), heap_fill_value,
+ std::memset(m_system.DeviceMemory().GetPointer<void>(it.GetAddress()), m_heap_fill_value,
it.GetSize());
}
// Map the pages.
{
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Ensure that the heap hasn't changed since we began executing.
- ASSERT(cur_address == current_heap_end);
+ ASSERT(cur_address == m_current_heap_end);
// Check the memory state.
- std::size_t num_allocator_blocks{};
- R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), current_heap_end,
+ size_t num_allocator_blocks{};
+ R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), m_current_heap_end,
allocation_size, KMemoryState::All, KMemoryState::Free,
KMemoryPermission::None, KMemoryPermission::None,
KMemoryAttribute::None, KMemoryAttribute::None));
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(
+ std::addressof(allocator_result), m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
// Map the pages.
const auto num_pages = allocation_size / PageSize;
- R_TRY(Operate(current_heap_end, num_pages, pg, OperationType::MapGroup));
+ R_TRY(Operate(m_current_heap_end, num_pages, pg, OperationType::MapGroup));
// Clear all the newly allocated pages.
- for (std::size_t cur_page = 0; cur_page < num_pages; ++cur_page) {
- std::memset(system.Memory().GetPointer(current_heap_end + (cur_page * PageSize)), 0,
+ for (size_t cur_page = 0; cur_page < num_pages; ++cur_page) {
+ std::memset(m_system.Memory().GetPointer(m_current_heap_end + (cur_page * PageSize)), 0,
PageSize);
}
@@ -1681,133 +1831,172 @@ Result KPageTable::SetHeapSize(VAddr* out, std::size_t size) {
memory_reservation.Commit();
// Apply the memory block update.
- block_manager->Update(current_heap_end, num_pages, KMemoryState::Normal,
- KMemoryPermission::UserReadWrite, KMemoryAttribute::None);
+ m_memory_block_manager.Update(
+ std::addressof(allocator), m_current_heap_end, num_pages, KMemoryState::Normal,
+ KMemoryPermission::UserReadWrite, KMemoryAttribute::None,
+ m_heap_region_start == m_current_heap_end ? KMemoryBlockDisableMergeAttribute::Normal
+ : KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::None);
// Update the current heap end.
- current_heap_end = heap_region_start + size;
+ m_current_heap_end = m_heap_region_start + size;
// Set the output.
- *out = heap_region_start;
- return ResultSuccess;
+ *out = m_heap_region_start;
+ R_SUCCEED();
}
}
-ResultVal<VAddr> KPageTable::AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align,
+ResultVal<VAddr> KPageTable::AllocateAndMapMemory(size_t needed_num_pages, size_t align,
bool is_map_only, VAddr region_start,
- std::size_t region_num_pages, KMemoryState state,
+ size_t region_num_pages, KMemoryState state,
KMemoryPermission perm, PAddr map_addr) {
- KScopedLightLock lk(general_lock);
-
- if (!CanContain(region_start, region_num_pages * PageSize, state)) {
- return ResultInvalidCurrentMemory;
- }
-
- if (region_num_pages <= needed_num_pages) {
- return ResultOutOfMemory;
- }
+ KScopedLightLock lk(m_general_lock);
+ R_UNLESS(CanContain(region_start, region_num_pages * PageSize, state),
+ ResultInvalidCurrentMemory);
+ R_UNLESS(region_num_pages > needed_num_pages, ResultOutOfMemory);
const VAddr addr{
AllocateVirtualMemory(region_start, region_num_pages, needed_num_pages, align)};
- if (!addr) {
- return ResultOutOfMemory;
- }
+ R_UNLESS(addr, ResultOutOfMemory);
+
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager);
if (is_map_only) {
R_TRY(Operate(addr, needed_num_pages, perm, OperationType::Map, map_addr));
} else {
KPageGroup page_group;
- R_TRY(system.Kernel().MemoryManager().AllocateAndOpenForProcess(
+ R_TRY(m_system.Kernel().MemoryManager().AllocateAndOpenForProcess(
&page_group, needed_num_pages,
- KMemoryManager::EncodeOption(memory_pool, allocation_option), 0, 0));
+ KMemoryManager::EncodeOption(m_memory_pool, m_allocation_option), 0, 0));
R_TRY(Operate(addr, needed_num_pages, page_group, OperationType::MapGroup));
}
- block_manager->Update(addr, needed_num_pages, state, perm);
+ // Update the blocks.
+ m_memory_block_manager.Update(std::addressof(allocator), addr, needed_num_pages, state, perm,
+ KMemoryAttribute::None, KMemoryBlockDisableMergeAttribute::Normal,
+ KMemoryBlockDisableMergeAttribute::None);
return addr;
}
-Result KPageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) {
- KScopedLightLock lk(general_lock);
-
- KMemoryPermission perm{};
- if (const Result result{CheckMemoryState(
- nullptr, &perm, nullptr, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute,
- KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None,
- KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None,
- KMemoryAttribute::DeviceSharedAndUncached)};
- result.IsError()) {
- return result;
- }
+Result KPageTable::LockForMapDeviceAddressSpace(VAddr address, size_t size, KMemoryPermission perm,
+ bool is_aligned) {
+ // Lightly validate the range before doing anything else.
+ const size_t num_pages = size / PageSize;
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
- block_manager->UpdateLock(
- addr, size / PageSize,
- [](KMemoryBlockManager::iterator block, KMemoryPermission permission) {
- block->ShareToDevice(permission);
- },
- perm);
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
- return ResultSuccess;
+ // Check the memory state.
+ const auto test_state =
+ (is_aligned ? KMemoryState::FlagCanAlignedDeviceMap : KMemoryState::FlagCanDeviceMap);
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryState(std::addressof(num_allocator_blocks), address, size, test_state,
+ test_state, perm, perm,
+ KMemoryAttribute::IpcLocked | KMemoryAttribute::Locked,
+ KMemoryAttribute::None, KMemoryAttribute::DeviceShared));
+
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // Update the memory blocks.
+ m_memory_block_manager.UpdateLock(std::addressof(allocator), address, num_pages,
+ &KMemoryBlock::ShareToDevice, KMemoryPermission::None);
+
+ R_SUCCEED();
}
-Result KPageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) {
- KScopedLightLock lk(general_lock);
-
- KMemoryPermission perm{};
- if (const Result result{CheckMemoryState(
- nullptr, &perm, nullptr, nullptr, addr, size, KMemoryState::FlagCanChangeAttribute,
- KMemoryState::FlagCanChangeAttribute, KMemoryPermission::None, KMemoryPermission::None,
- KMemoryAttribute::LockedAndIpcLocked, KMemoryAttribute::None,
- KMemoryAttribute::DeviceSharedAndUncached)};
- result.IsError()) {
- return result;
- }
+Result KPageTable::LockForUnmapDeviceAddressSpace(VAddr address, size_t size) {
+ // Lightly validate the range before doing anything else.
+ const size_t num_pages = size / PageSize;
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
- block_manager->UpdateLock(
- addr, size / PageSize,
- [](KMemoryBlockManager::iterator block, KMemoryPermission permission) {
- block->UnshareToDevice(permission);
- },
- perm);
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
- return ResultSuccess;
+ // Check the memory state.
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryStateContiguous(
+ std::addressof(num_allocator_blocks), address, size,
+ KMemoryState::FlagReferenceCounted | KMemoryState::FlagCanDeviceMap,
+ KMemoryState::FlagReferenceCounted | KMemoryState::FlagCanDeviceMap,
+ KMemoryPermission::None, KMemoryPermission::None,
+ KMemoryAttribute::DeviceShared | KMemoryAttribute::Locked, KMemoryAttribute::DeviceShared));
+
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // Update the memory blocks.
+ const KMemoryBlockManager::MemoryBlockLockFunction lock_func =
+ m_enable_device_address_space_merge
+ ? &KMemoryBlock::UpdateDeviceDisableMergeStateForShare
+ : &KMemoryBlock::UpdateDeviceDisableMergeStateForShareRight;
+ m_memory_block_manager.UpdateLock(std::addressof(allocator), address, num_pages, lock_func,
+ KMemoryPermission::None);
+
+ R_SUCCEED();
}
-Result KPageTable::LockForCodeMemory(KPageGroup* out, VAddr addr, std::size_t size) {
- return this->LockMemoryAndOpen(
+Result KPageTable::UnlockForDeviceAddressSpace(VAddr address, size_t size) {
+ // Lightly validate the range before doing anything else.
+ const size_t num_pages = size / PageSize;
+ R_UNLESS(this->Contains(address, size), ResultInvalidCurrentMemory);
+
+ // Lock the table.
+ KScopedLightLock lk(m_general_lock);
+
+ // Check the memory state.
+ size_t num_allocator_blocks;
+ R_TRY(this->CheckMemoryStateContiguous(
+ std::addressof(num_allocator_blocks), address, size, KMemoryState::FlagCanDeviceMap,
+ KMemoryState::FlagCanDeviceMap, KMemoryPermission::None, KMemoryPermission::None,
+ KMemoryAttribute::DeviceShared | KMemoryAttribute::Locked, KMemoryAttribute::DeviceShared));
+
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
+ // Update the memory blocks.
+ m_memory_block_manager.UpdateLock(std::addressof(allocator), address, num_pages,
+ &KMemoryBlock::UnshareToDevice, KMemoryPermission::None);
+
+ R_SUCCEED();
+}
+
+Result KPageTable::LockForCodeMemory(KPageGroup* out, VAddr addr, size_t size) {
+ R_RETURN(this->LockMemoryAndOpen(
out, nullptr, addr, size, KMemoryState::FlagCanCodeMemory, KMemoryState::FlagCanCodeMemory,
KMemoryPermission::All, KMemoryPermission::UserReadWrite, KMemoryAttribute::All,
KMemoryAttribute::None,
static_cast<KMemoryPermission>(KMemoryPermission::NotMapped |
KMemoryPermission::KernelReadWrite),
- KMemoryAttribute::Locked);
+ KMemoryAttribute::Locked));
}
-Result KPageTable::UnlockForCodeMemory(VAddr addr, std::size_t size, const KPageGroup& pg) {
- return this->UnlockMemory(
+Result KPageTable::UnlockForCodeMemory(VAddr addr, size_t size, const KPageGroup& pg) {
+ R_RETURN(this->UnlockMemory(
addr, size, KMemoryState::FlagCanCodeMemory, KMemoryState::FlagCanCodeMemory,
KMemoryPermission::None, KMemoryPermission::None, KMemoryAttribute::All,
- KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite, KMemoryAttribute::Locked, &pg);
-}
-
-Result KPageTable::InitializeMemoryLayout(VAddr start, VAddr end) {
- block_manager = std::make_unique<KMemoryBlockManager>(start, end);
-
- return ResultSuccess;
-}
-
-bool KPageTable::IsRegionMapped(VAddr address, u64 size) {
- return CheckMemoryState(address, size, KMemoryState::All, KMemoryState::Free,
- KMemoryPermission::All, KMemoryPermission::None, KMemoryAttribute::Mask,
- KMemoryAttribute::None, KMemoryAttribute::IpcAndDeviceMapped)
- .IsError();
+ KMemoryAttribute::Locked, KMemoryPermission::UserReadWrite, KMemoryAttribute::Locked, &pg));
}
bool KPageTable::IsRegionContiguous(VAddr addr, u64 size) const {
- auto start_ptr = system.Memory().GetPointer(addr);
+ auto start_ptr = m_system.DeviceMemory().GetPointer<u8>(addr);
for (u64 offset{}; offset < size; offset += PageSize) {
- if (start_ptr != system.Memory().GetPointer(addr + offset)) {
+ if (start_ptr != m_system.DeviceMemory().GetPointer<u8>(addr + offset)) {
return false;
}
start_ptr += PageSize;
@@ -1815,8 +2004,7 @@ bool KPageTable::IsRegionContiguous(VAddr addr, u64 size) const {
return true;
}
-void KPageTable::AddRegionToPages(VAddr start, std::size_t num_pages,
- KPageGroup& page_linked_list) {
+void KPageTable::AddRegionToPages(VAddr start, size_t num_pages, KPageGroup& page_linked_list) {
VAddr addr{start};
while (addr < start + (num_pages * PageSize)) {
const PAddr paddr{GetPhysicalAddr(addr)};
@@ -1826,16 +2014,16 @@ void KPageTable::AddRegionToPages(VAddr start, std::size_t num_pages,
}
}
-VAddr KPageTable::AllocateVirtualMemory(VAddr start, std::size_t region_num_pages,
- u64 needed_num_pages, std::size_t align) {
- if (is_aslr_enabled) {
+VAddr KPageTable::AllocateVirtualMemory(VAddr start, size_t region_num_pages, u64 needed_num_pages,
+ size_t align) {
+ if (m_enable_aslr) {
UNIMPLEMENTED();
}
- return block_manager->FindFreeArea(start, region_num_pages, needed_num_pages, align, 0,
- IsKernel() ? 1 : 4);
+ return m_memory_block_manager.FindFreeArea(start, region_num_pages, needed_num_pages, align, 0,
+ IsKernel() ? 1 : 4);
}
-Result KPageTable::Operate(VAddr addr, std::size_t num_pages, const KPageGroup& page_group,
+Result KPageTable::Operate(VAddr addr, size_t num_pages, const KPageGroup& page_group,
OperationType operation) {
ASSERT(this->IsLockedByCurrentThread());
@@ -1844,11 +2032,11 @@ Result KPageTable::Operate(VAddr addr, std::size_t num_pages, const KPageGroup&
ASSERT(num_pages == page_group.GetNumPages());
for (const auto& node : page_group.Nodes()) {
- const std::size_t size{node.GetNumPages() * PageSize};
+ const size_t size{node.GetNumPages() * PageSize};
switch (operation) {
case OperationType::MapGroup:
- system.Memory().MapMemoryRegion(page_table_impl, addr, size, node.GetAddress());
+ m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, size, node.GetAddress());
break;
default:
ASSERT(false);
@@ -1857,10 +2045,10 @@ Result KPageTable::Operate(VAddr addr, std::size_t num_pages, const KPageGroup&
addr += size;
}
- return ResultSuccess;
+ R_SUCCEED();
}
-Result KPageTable::Operate(VAddr addr, std::size_t num_pages, KMemoryPermission perm,
+Result KPageTable::Operate(VAddr addr, size_t num_pages, KMemoryPermission perm,
OperationType operation, PAddr map_addr) {
ASSERT(this->IsLockedByCurrentThread());
@@ -1870,12 +2058,12 @@ Result KPageTable::Operate(VAddr addr, std::size_t num_pages, KMemoryPermission
switch (operation) {
case OperationType::Unmap:
- system.Memory().UnmapRegion(page_table_impl, addr, num_pages * PageSize);
+ m_system.Memory().UnmapRegion(*m_page_table_impl, addr, num_pages * PageSize);
break;
case OperationType::Map: {
ASSERT(map_addr);
ASSERT(Common::IsAligned(map_addr, PageSize));
- system.Memory().MapMemoryRegion(page_table_impl, addr, num_pages * PageSize, map_addr);
+ m_system.Memory().MapMemoryRegion(*m_page_table_impl, addr, num_pages * PageSize, map_addr);
break;
}
case OperationType::ChangePermissions:
@@ -1884,25 +2072,25 @@ Result KPageTable::Operate(VAddr addr, std::size_t num_pages, KMemoryPermission
default:
ASSERT(false);
}
- return ResultSuccess;
+ R_SUCCEED();
}
VAddr KPageTable::GetRegionAddress(KMemoryState state) const {
switch (state) {
case KMemoryState::Free:
case KMemoryState::Kernel:
- return address_space_start;
+ return m_address_space_start;
case KMemoryState::Normal:
- return heap_region_start;
+ return m_heap_region_start;
case KMemoryState::Ipc:
case KMemoryState::NonSecureIpc:
case KMemoryState::NonDeviceIpc:
- return alias_region_start;
+ return m_alias_region_start;
case KMemoryState::Stack:
- return stack_region_start;
+ return m_stack_region_start;
case KMemoryState::Static:
case KMemoryState::ThreadLocal:
- return kernel_map_region_start;
+ return m_kernel_map_region_start;
case KMemoryState::Io:
case KMemoryState::Shared:
case KMemoryState::AliasCode:
@@ -1913,31 +2101,31 @@ VAddr KPageTable::GetRegionAddress(KMemoryState state) const {
case KMemoryState::GeneratedCode:
case KMemoryState::CodeOut:
case KMemoryState::Coverage:
- return alias_code_region_start;
+ return m_alias_code_region_start;
case KMemoryState::Code:
case KMemoryState::CodeData:
- return code_region_start;
+ return m_code_region_start;
default:
UNREACHABLE();
}
}
-std::size_t KPageTable::GetRegionSize(KMemoryState state) const {
+size_t KPageTable::GetRegionSize(KMemoryState state) const {
switch (state) {
case KMemoryState::Free:
case KMemoryState::Kernel:
- return address_space_end - address_space_start;
+ return m_address_space_end - m_address_space_start;
case KMemoryState::Normal:
- return heap_region_end - heap_region_start;
+ return m_heap_region_end - m_heap_region_start;
case KMemoryState::Ipc:
case KMemoryState::NonSecureIpc:
case KMemoryState::NonDeviceIpc:
- return alias_region_end - alias_region_start;
+ return m_alias_region_end - m_alias_region_start;
case KMemoryState::Stack:
- return stack_region_end - stack_region_start;
+ return m_stack_region_end - m_stack_region_start;
case KMemoryState::Static:
case KMemoryState::ThreadLocal:
- return kernel_map_region_end - kernel_map_region_start;
+ return m_kernel_map_region_end - m_kernel_map_region_start;
case KMemoryState::Io:
case KMemoryState::Shared:
case KMemoryState::AliasCode:
@@ -1948,16 +2136,16 @@ std::size_t KPageTable::GetRegionSize(KMemoryState state) const {
case KMemoryState::GeneratedCode:
case KMemoryState::CodeOut:
case KMemoryState::Coverage:
- return alias_code_region_end - alias_code_region_start;
+ return m_alias_code_region_end - m_alias_code_region_start;
case KMemoryState::Code:
case KMemoryState::CodeData:
- return code_region_end - code_region_start;
+ return m_code_region_end - m_code_region_start;
default:
UNREACHABLE();
}
}
-bool KPageTable::CanContain(VAddr addr, std::size_t size, KMemoryState state) const {
+bool KPageTable::CanContain(VAddr addr, size_t size, KMemoryState state) const {
const VAddr end = addr + size;
const VAddr last = end - 1;
@@ -1966,10 +2154,10 @@ bool KPageTable::CanContain(VAddr addr, std::size_t size, KMemoryState state) co
const bool is_in_region =
region_start <= addr && addr < end && last <= region_start + region_size - 1;
- const bool is_in_heap = !(end <= heap_region_start || heap_region_end <= addr ||
- heap_region_start == heap_region_end);
- const bool is_in_alias = !(end <= alias_region_start || alias_region_end <= addr ||
- alias_region_start == alias_region_end);
+ const bool is_in_heap = !(end <= m_heap_region_start || m_heap_region_end <= addr ||
+ m_heap_region_start == m_heap_region_end);
+ const bool is_in_alias = !(end <= m_alias_region_start || m_alias_region_end <= addr ||
+ m_alias_region_start == m_alias_region_end);
switch (state) {
case KMemoryState::Free:
case KMemoryState::Kernel:
@@ -2008,23 +2196,23 @@ Result KPageTable::CheckMemoryState(const KMemoryInfo& info, KMemoryState state_
KMemoryPermission perm, KMemoryAttribute attr_mask,
KMemoryAttribute attr) const {
// Validate the states match expectation.
- R_UNLESS((info.state & state_mask) == state, ResultInvalidCurrentMemory);
- R_UNLESS((info.perm & perm_mask) == perm, ResultInvalidCurrentMemory);
- R_UNLESS((info.attribute & attr_mask) == attr, ResultInvalidCurrentMemory);
+ R_UNLESS((info.m_state & state_mask) == state, ResultInvalidCurrentMemory);
+ R_UNLESS((info.m_permission & perm_mask) == perm, ResultInvalidCurrentMemory);
+ R_UNLESS((info.m_attribute & attr_mask) == attr, ResultInvalidCurrentMemory);
- return ResultSuccess;
+ R_SUCCEED();
}
-Result KPageTable::CheckMemoryStateContiguous(std::size_t* out_blocks_needed, VAddr addr,
- std::size_t size, KMemoryState state_mask,
- KMemoryState state, KMemoryPermission perm_mask,
- KMemoryPermission perm, KMemoryAttribute attr_mask,
+Result KPageTable::CheckMemoryStateContiguous(size_t* out_blocks_needed, VAddr addr, size_t size,
+ KMemoryState state_mask, KMemoryState state,
+ KMemoryPermission perm_mask, KMemoryPermission perm,
+ KMemoryAttribute attr_mask,
KMemoryAttribute attr) const {
ASSERT(this->IsLockedByCurrentThread());
// Get information about the first block.
const VAddr last_addr = addr + size - 1;
- KMemoryBlockManager::const_iterator it = block_manager->FindIterator(addr);
+ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr);
KMemoryInfo info = it->GetMemoryInfo();
// If the start address isn't aligned, we need a block.
@@ -2042,7 +2230,7 @@ Result KPageTable::CheckMemoryStateContiguous(std::size_t* out_blocks_needed, VA
// Advance our iterator.
it++;
- ASSERT(it != block_manager->cend());
+ ASSERT(it != m_memory_block_manager.cend());
info = it->GetMemoryInfo();
}
@@ -2054,12 +2242,12 @@ Result KPageTable::CheckMemoryStateContiguous(std::size_t* out_blocks_needed, VA
*out_blocks_needed = blocks_for_start_align + blocks_for_end_align;
}
- return ResultSuccess;
+ R_SUCCEED();
}
Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
- KMemoryAttribute* out_attr, std::size_t* out_blocks_needed,
- VAddr addr, std::size_t size, KMemoryState state_mask,
+ KMemoryAttribute* out_attr, size_t* out_blocks_needed,
+ VAddr addr, size_t size, KMemoryState state_mask,
KMemoryState state, KMemoryPermission perm_mask,
KMemoryPermission perm, KMemoryAttribute attr_mask,
KMemoryAttribute attr, KMemoryAttribute ignore_attr) const {
@@ -2067,7 +2255,7 @@ Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission*
// Get information about the first block.
const VAddr last_addr = addr + size - 1;
- KMemoryBlockManager::const_iterator it = block_manager->FindIterator(addr);
+ KMemoryBlockManager::const_iterator it = m_memory_block_manager.FindIterator(addr);
KMemoryInfo info = it->GetMemoryInfo();
// If the start address isn't aligned, we need a block.
@@ -2075,14 +2263,14 @@ Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission*
(Common::AlignDown(addr, PageSize) != info.GetAddress()) ? 1 : 0;
// Validate all blocks in the range have correct state.
- const KMemoryState first_state = info.state;
- const KMemoryPermission first_perm = info.perm;
- const KMemoryAttribute first_attr = info.attribute;
+ const KMemoryState first_state = info.m_state;
+ const KMemoryPermission first_perm = info.m_permission;
+ const KMemoryAttribute first_attr = info.m_attribute;
while (true) {
// Validate the current block.
- R_UNLESS(info.state == first_state, ResultInvalidCurrentMemory);
- R_UNLESS(info.perm == first_perm, ResultInvalidCurrentMemory);
- R_UNLESS((info.attribute | ignore_attr) == (first_attr | ignore_attr),
+ R_UNLESS(info.m_state == first_state, ResultInvalidCurrentMemory);
+ R_UNLESS(info.m_permission == first_perm, ResultInvalidCurrentMemory);
+ R_UNLESS((info.m_attribute | ignore_attr) == (first_attr | ignore_attr),
ResultInvalidCurrentMemory);
// Validate against the provided masks.
@@ -2095,7 +2283,7 @@ Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission*
// Advance our iterator.
it++;
- ASSERT(it != block_manager->cend());
+ ASSERT(it != m_memory_block_manager.cend());
info = it->GetMemoryInfo();
}
@@ -2116,7 +2304,7 @@ Result KPageTable::CheckMemoryState(KMemoryState* out_state, KMemoryPermission*
if (out_blocks_needed != nullptr) {
*out_blocks_needed = blocks_for_start_align + blocks_for_end_align;
}
- return ResultSuccess;
+ R_SUCCEED();
}
Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr addr, size_t size,
@@ -2134,7 +2322,7 @@ Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr
R_UNLESS(this->Contains(addr, size), ResultInvalidCurrentMemory);
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Check that the output page group is empty, if it exists.
if (out_pg) {
@@ -2162,6 +2350,12 @@ Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr
R_TRY(this->MakePageGroup(*out_pg, addr, num_pages));
}
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
// Decide on new perm and attr.
new_perm = (new_perm != KMemoryPermission::None) ? new_perm : old_perm;
KMemoryAttribute new_attr = static_cast<KMemoryAttribute>(old_attr | lock_attr);
@@ -2172,9 +2366,11 @@ Result KPageTable::LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr
}
// Apply the memory block updates.
- block_manager->Update(addr, num_pages, old_state, new_perm, new_attr);
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, new_perm,
+ new_attr, KMemoryBlockDisableMergeAttribute::Locked,
+ KMemoryBlockDisableMergeAttribute::None);
- return ResultSuccess;
+ R_SUCCEED();
}
Result KPageTable::UnlockMemory(VAddr addr, size_t size, KMemoryState state_mask,
@@ -2191,7 +2387,7 @@ Result KPageTable::UnlockMemory(VAddr addr, size_t size, KMemoryState state_mask
R_UNLESS(this->Contains(addr, size), ResultInvalidCurrentMemory);
// Lock the table.
- KScopedLightLock lk(general_lock);
+ KScopedLightLock lk(m_general_lock);
// Check the state.
KMemoryState old_state{};
@@ -2213,15 +2409,23 @@ Result KPageTable::UnlockMemory(VAddr addr, size_t size, KMemoryState state_mask
new_perm = (new_perm != KMemoryPermission::None) ? new_perm : old_perm;
KMemoryAttribute new_attr = static_cast<KMemoryAttribute>(old_attr & ~lock_attr);
+ // Create an update allocator.
+ Result allocator_result{ResultSuccess};
+ KMemoryBlockManagerUpdateAllocator allocator(std::addressof(allocator_result),
+ m_memory_block_slab_manager, num_allocator_blocks);
+ R_TRY(allocator_result);
+
// Update permission, if we need to.
if (new_perm != old_perm) {
R_TRY(Operate(addr, num_pages, new_perm, OperationType::ChangePermissions));
}
// Apply the memory block updates.
- block_manager->Update(addr, num_pages, old_state, new_perm, new_attr);
+ m_memory_block_manager.Update(std::addressof(allocator), addr, num_pages, old_state, new_perm,
+ new_attr, KMemoryBlockDisableMergeAttribute::None,
+ KMemoryBlockDisableMergeAttribute::Locked);
- return ResultSuccess;
+ R_SUCCEED();
}
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h
index 25774f232..c6aeacd96 100644
--- a/src/core/hle/kernel/k_page_table.h
+++ b/src/core/hle/kernel/k_page_table.h
@@ -9,8 +9,10 @@
#include "common/common_types.h"
#include "common/page_table.h"
#include "core/file_sys/program_metadata.h"
+#include "core/hle/kernel/k_dynamic_resource_manager.h"
#include "core/hle/kernel/k_light_lock.h"
#include "core/hle/kernel/k_memory_block.h"
+#include "core/hle/kernel/k_memory_block_manager.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_memory_manager.h"
#include "core/hle/result.h"
@@ -34,58 +36,66 @@ public:
~KPageTable();
Result InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
- VAddr code_addr, std::size_t code_size, KMemoryManager::Pool pool);
- Result MapProcessCode(VAddr addr, std::size_t pages_count, KMemoryState state,
+ VAddr code_addr, size_t code_size,
+ KMemoryBlockSlabManager* mem_block_slab_manager,
+ KMemoryManager::Pool pool);
+
+ void Finalize();
+
+ Result MapProcessCode(VAddr addr, size_t pages_count, KMemoryState state,
KMemoryPermission perm);
- Result MapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size);
- Result UnmapCodeMemory(VAddr dst_address, VAddr src_address, std::size_t size,
+ Result MapCodeMemory(VAddr dst_address, VAddr src_address, size_t size);
+ Result UnmapCodeMemory(VAddr dst_address, VAddr src_address, size_t size,
ICacheInvalidationStrategy icache_invalidation_strategy);
- Result UnmapProcessMemory(VAddr dst_addr, std::size_t size, KPageTable& src_page_table,
+ Result UnmapProcessMemory(VAddr dst_addr, size_t size, KPageTable& src_page_table,
VAddr src_addr);
- Result MapPhysicalMemory(VAddr addr, std::size_t size);
- Result UnmapPhysicalMemory(VAddr addr, std::size_t size);
- Result MapMemory(VAddr dst_addr, VAddr src_addr, std::size_t size);
- Result UnmapMemory(VAddr dst_addr, VAddr src_addr, std::size_t size);
+ Result MapPhysicalMemory(VAddr addr, size_t size);
+ Result UnmapPhysicalMemory(VAddr addr, size_t size);
+ Result MapMemory(VAddr dst_addr, VAddr src_addr, size_t size);
+ Result UnmapMemory(VAddr dst_addr, VAddr src_addr, size_t size);
Result MapPages(VAddr addr, KPageGroup& page_linked_list, KMemoryState state,
KMemoryPermission perm);
- Result MapPages(VAddr* out_addr, std::size_t num_pages, std::size_t alignment, PAddr phys_addr,
+ Result MapPages(VAddr* out_addr, size_t num_pages, size_t alignment, PAddr phys_addr,
KMemoryState state, KMemoryPermission perm) {
- return this->MapPages(out_addr, num_pages, alignment, phys_addr, true,
- this->GetRegionAddress(state), this->GetRegionSize(state) / PageSize,
- state, perm);
+ R_RETURN(this->MapPages(out_addr, num_pages, alignment, phys_addr, true,
+ this->GetRegionAddress(state),
+ this->GetRegionSize(state) / PageSize, state, perm));
}
Result UnmapPages(VAddr addr, KPageGroup& page_linked_list, KMemoryState state);
- Result UnmapPages(VAddr address, std::size_t num_pages, KMemoryState state);
- Result SetProcessMemoryPermission(VAddr addr, std::size_t size, Svc::MemoryPermission svc_perm);
+ Result UnmapPages(VAddr address, size_t num_pages, KMemoryState state);
+ Result SetProcessMemoryPermission(VAddr addr, size_t size, Svc::MemoryPermission svc_perm);
KMemoryInfo QueryInfo(VAddr addr);
- Result ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm);
- Result ResetTransferMemory(VAddr addr, std::size_t size);
- Result SetMemoryPermission(VAddr addr, std::size_t size, Svc::MemoryPermission perm);
- Result SetMemoryAttribute(VAddr addr, std::size_t size, u32 mask, u32 attr);
- Result SetMaxHeapSize(std::size_t size);
- Result SetHeapSize(VAddr* out, std::size_t size);
- ResultVal<VAddr> AllocateAndMapMemory(std::size_t needed_num_pages, std::size_t align,
- bool is_map_only, VAddr region_start,
- std::size_t region_num_pages, KMemoryState state,
- KMemoryPermission perm, PAddr map_addr = 0);
- Result LockForDeviceAddressSpace(VAddr addr, std::size_t size);
- Result UnlockForDeviceAddressSpace(VAddr addr, std::size_t size);
- Result LockForCodeMemory(KPageGroup* out, VAddr addr, std::size_t size);
- Result UnlockForCodeMemory(VAddr addr, std::size_t size, const KPageGroup& pg);
+ Result SetMemoryPermission(VAddr addr, size_t size, Svc::MemoryPermission perm);
+ Result SetMemoryAttribute(VAddr addr, size_t size, u32 mask, u32 attr);
+ Result SetMaxHeapSize(size_t size);
+ Result SetHeapSize(VAddr* out, size_t size);
+ ResultVal<VAddr> AllocateAndMapMemory(size_t needed_num_pages, size_t align, bool is_map_only,
+ VAddr region_start, size_t region_num_pages,
+ KMemoryState state, KMemoryPermission perm,
+ PAddr map_addr = 0);
+
+ Result LockForMapDeviceAddressSpace(VAddr address, size_t size, KMemoryPermission perm,
+ bool is_aligned);
+ Result LockForUnmapDeviceAddressSpace(VAddr address, size_t size);
+
+ Result UnlockForDeviceAddressSpace(VAddr addr, size_t size);
+
+ Result LockForCodeMemory(KPageGroup* out, VAddr addr, size_t size);
+ Result UnlockForCodeMemory(VAddr addr, size_t size, const KPageGroup& pg);
Result MakeAndOpenPageGroup(KPageGroup* out, VAddr address, size_t num_pages,
KMemoryState state_mask, KMemoryState state,
KMemoryPermission perm_mask, KMemoryPermission perm,
KMemoryAttribute attr_mask, KMemoryAttribute attr);
Common::PageTable& PageTableImpl() {
- return page_table_impl;
+ return *m_page_table_impl;
}
const Common::PageTable& PageTableImpl() const {
- return page_table_impl;
+ return *m_page_table_impl;
}
- bool CanContain(VAddr addr, std::size_t size, KMemoryState state) const;
+ bool CanContain(VAddr addr, size_t size, KMemoryState state) const;
private:
enum class OperationType : u32 {
@@ -96,67 +106,65 @@ private:
ChangePermissionsAndRefresh,
};
- static constexpr KMemoryAttribute DefaultMemoryIgnoreAttr = KMemoryAttribute::DontCareMask |
- KMemoryAttribute::IpcLocked |
- KMemoryAttribute::DeviceShared;
+ static constexpr KMemoryAttribute DefaultMemoryIgnoreAttr =
+ KMemoryAttribute::IpcLocked | KMemoryAttribute::DeviceShared;
- Result InitializeMemoryLayout(VAddr start, VAddr end);
Result MapPages(VAddr addr, const KPageGroup& page_linked_list, KMemoryPermission perm);
- Result MapPages(VAddr* out_addr, std::size_t num_pages, std::size_t alignment, PAddr phys_addr,
- bool is_pa_valid, VAddr region_start, std::size_t region_num_pages,
+ Result MapPages(VAddr* out_addr, size_t num_pages, size_t alignment, PAddr phys_addr,
+ bool is_pa_valid, VAddr region_start, size_t region_num_pages,
KMemoryState state, KMemoryPermission perm);
Result UnmapPages(VAddr addr, const KPageGroup& page_linked_list);
- bool IsRegionMapped(VAddr address, u64 size);
bool IsRegionContiguous(VAddr addr, u64 size) const;
- void AddRegionToPages(VAddr start, std::size_t num_pages, KPageGroup& page_linked_list);
+ void AddRegionToPages(VAddr start, size_t num_pages, KPageGroup& page_linked_list);
KMemoryInfo QueryInfoImpl(VAddr addr);
- VAddr AllocateVirtualMemory(VAddr start, std::size_t region_num_pages, u64 needed_num_pages,
- std::size_t align);
- Result Operate(VAddr addr, std::size_t num_pages, const KPageGroup& page_group,
+ VAddr AllocateVirtualMemory(VAddr start, size_t region_num_pages, u64 needed_num_pages,
+ size_t align);
+ Result Operate(VAddr addr, size_t num_pages, const KPageGroup& page_group,
OperationType operation);
- Result Operate(VAddr addr, std::size_t num_pages, KMemoryPermission perm,
- OperationType operation, PAddr map_addr = 0);
+ Result Operate(VAddr addr, size_t num_pages, KMemoryPermission perm, OperationType operation,
+ PAddr map_addr = 0);
VAddr GetRegionAddress(KMemoryState state) const;
- std::size_t GetRegionSize(KMemoryState state) const;
+ size_t GetRegionSize(KMemoryState state) const;
- VAddr FindFreeArea(VAddr region_start, std::size_t region_num_pages, std::size_t num_pages,
- std::size_t alignment, std::size_t offset, std::size_t guard_pages);
+ VAddr FindFreeArea(VAddr region_start, size_t region_num_pages, size_t num_pages,
+ size_t alignment, size_t offset, size_t guard_pages);
- Result CheckMemoryStateContiguous(std::size_t* out_blocks_needed, VAddr addr, std::size_t size,
+ Result CheckMemoryStateContiguous(size_t* out_blocks_needed, VAddr addr, size_t size,
KMemoryState state_mask, KMemoryState state,
KMemoryPermission perm_mask, KMemoryPermission perm,
KMemoryAttribute attr_mask, KMemoryAttribute attr) const;
- Result CheckMemoryStateContiguous(VAddr addr, std::size_t size, KMemoryState state_mask,
+ Result CheckMemoryStateContiguous(VAddr addr, size_t size, KMemoryState state_mask,
KMemoryState state, KMemoryPermission perm_mask,
KMemoryPermission perm, KMemoryAttribute attr_mask,
KMemoryAttribute attr) const {
- return this->CheckMemoryStateContiguous(nullptr, addr, size, state_mask, state, perm_mask,
- perm, attr_mask, attr);
+ R_RETURN(this->CheckMemoryStateContiguous(nullptr, addr, size, state_mask, state, perm_mask,
+ perm, attr_mask, attr));
}
Result CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, KMemoryState state,
KMemoryPermission perm_mask, KMemoryPermission perm,
KMemoryAttribute attr_mask, KMemoryAttribute attr) const;
Result CheckMemoryState(KMemoryState* out_state, KMemoryPermission* out_perm,
- KMemoryAttribute* out_attr, std::size_t* out_blocks_needed, VAddr addr,
- std::size_t size, KMemoryState state_mask, KMemoryState state,
+ KMemoryAttribute* out_attr, size_t* out_blocks_needed, VAddr addr,
+ size_t size, KMemoryState state_mask, KMemoryState state,
KMemoryPermission perm_mask, KMemoryPermission perm,
KMemoryAttribute attr_mask, KMemoryAttribute attr,
KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const;
- Result CheckMemoryState(std::size_t* out_blocks_needed, VAddr addr, std::size_t size,
+ Result CheckMemoryState(size_t* out_blocks_needed, VAddr addr, size_t size,
KMemoryState state_mask, KMemoryState state,
KMemoryPermission perm_mask, KMemoryPermission perm,
KMemoryAttribute attr_mask, KMemoryAttribute attr,
KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const {
- return CheckMemoryState(nullptr, nullptr, nullptr, out_blocks_needed, addr, size,
- state_mask, state, perm_mask, perm, attr_mask, attr, ignore_attr);
+ R_RETURN(CheckMemoryState(nullptr, nullptr, nullptr, out_blocks_needed, addr, size,
+ state_mask, state, perm_mask, perm, attr_mask, attr,
+ ignore_attr));
}
- Result CheckMemoryState(VAddr addr, std::size_t size, KMemoryState state_mask,
- KMemoryState state, KMemoryPermission perm_mask, KMemoryPermission perm,
+ Result CheckMemoryState(VAddr addr, size_t size, KMemoryState state_mask, KMemoryState state,
+ KMemoryPermission perm_mask, KMemoryPermission perm,
KMemoryAttribute attr_mask, KMemoryAttribute attr,
KMemoryAttribute ignore_attr = DefaultMemoryIgnoreAttr) const {
- return this->CheckMemoryState(nullptr, addr, size, state_mask, state, perm_mask, perm,
- attr_mask, attr, ignore_attr);
+ R_RETURN(this->CheckMemoryState(nullptr, addr, size, state_mask, state, perm_mask, perm,
+ attr_mask, attr, ignore_attr));
}
Result LockMemoryAndOpen(KPageGroup* out_pg, PAddr* out_paddr, VAddr addr, size_t size,
@@ -174,13 +182,13 @@ private:
bool IsValidPageGroup(const KPageGroup& pg, VAddr addr, size_t num_pages);
bool IsLockedByCurrentThread() const {
- return general_lock.IsLockedByCurrentThread();
+ return m_general_lock.IsLockedByCurrentThread();
}
bool IsHeapPhysicalAddress(const KMemoryLayout& layout, PAddr phys_addr) {
ASSERT(this->IsLockedByCurrentThread());
- return layout.IsHeapPhysicalAddress(cached_physical_heap_region, phys_addr);
+ return layout.IsHeapPhysicalAddress(m_cached_physical_heap_region, phys_addr);
}
bool GetPhysicalAddressLocked(PAddr* out, VAddr virt_addr) const {
@@ -191,95 +199,93 @@ private:
return *out != 0;
}
- mutable KLightLock general_lock;
- mutable KLightLock map_physical_memory_lock;
-
- std::unique_ptr<KMemoryBlockManager> block_manager;
+ mutable KLightLock m_general_lock;
+ mutable KLightLock m_map_physical_memory_lock;
public:
constexpr VAddr GetAddressSpaceStart() const {
- return address_space_start;
+ return m_address_space_start;
}
constexpr VAddr GetAddressSpaceEnd() const {
- return address_space_end;
+ return m_address_space_end;
}
- constexpr std::size_t GetAddressSpaceSize() const {
- return address_space_end - address_space_start;
+ constexpr size_t GetAddressSpaceSize() const {
+ return m_address_space_end - m_address_space_start;
}
constexpr VAddr GetHeapRegionStart() const {
- return heap_region_start;
+ return m_heap_region_start;
}
constexpr VAddr GetHeapRegionEnd() const {
- return heap_region_end;
+ return m_heap_region_end;
}
- constexpr std::size_t GetHeapRegionSize() const {
- return heap_region_end - heap_region_start;
+ constexpr size_t GetHeapRegionSize() const {
+ return m_heap_region_end - m_heap_region_start;
}
constexpr VAddr GetAliasRegionStart() const {
- return alias_region_start;
+ return m_alias_region_start;
}
constexpr VAddr GetAliasRegionEnd() const {
- return alias_region_end;
+ return m_alias_region_end;
}
- constexpr std::size_t GetAliasRegionSize() const {
- return alias_region_end - alias_region_start;
+ constexpr size_t GetAliasRegionSize() const {
+ return m_alias_region_end - m_alias_region_start;
}
constexpr VAddr GetStackRegionStart() const {
- return stack_region_start;
+ return m_stack_region_start;
}
constexpr VAddr GetStackRegionEnd() const {
- return stack_region_end;
+ return m_stack_region_end;
}
- constexpr std::size_t GetStackRegionSize() const {
- return stack_region_end - stack_region_start;
+ constexpr size_t GetStackRegionSize() const {
+ return m_stack_region_end - m_stack_region_start;
}
constexpr VAddr GetKernelMapRegionStart() const {
- return kernel_map_region_start;
+ return m_kernel_map_region_start;
}
constexpr VAddr GetKernelMapRegionEnd() const {
- return kernel_map_region_end;
+ return m_kernel_map_region_end;
}
constexpr VAddr GetCodeRegionStart() const {
- return code_region_start;
+ return m_code_region_start;
}
constexpr VAddr GetCodeRegionEnd() const {
- return code_region_end;
+ return m_code_region_end;
}
constexpr VAddr GetAliasCodeRegionStart() const {
- return alias_code_region_start;
+ return m_alias_code_region_start;
}
constexpr VAddr GetAliasCodeRegionSize() const {
- return alias_code_region_end - alias_code_region_start;
+ return m_alias_code_region_end - m_alias_code_region_start;
}
- std::size_t GetNormalMemorySize() {
- KScopedLightLock lk(general_lock);
- return GetHeapSize() + mapped_physical_memory_size;
+ size_t GetNormalMemorySize() {
+ KScopedLightLock lk(m_general_lock);
+ return GetHeapSize() + m_mapped_physical_memory_size;
}
- constexpr std::size_t GetAddressSpaceWidth() const {
- return address_space_width;
+ constexpr size_t GetAddressSpaceWidth() const {
+ return m_address_space_width;
}
- constexpr std::size_t GetHeapSize() const {
- return current_heap_end - heap_region_start;
+ constexpr size_t GetHeapSize() const {
+ return m_current_heap_end - m_heap_region_start;
}
- constexpr bool IsInsideAddressSpace(VAddr address, std::size_t size) const {
- return address_space_start <= address && address + size - 1 <= address_space_end - 1;
+ constexpr bool IsInsideAddressSpace(VAddr address, size_t size) const {
+ return m_address_space_start <= address && address + size - 1 <= m_address_space_end - 1;
}
- constexpr bool IsOutsideAliasRegion(VAddr address, std::size_t size) const {
- return alias_region_start > address || address + size - 1 > alias_region_end - 1;
+ constexpr bool IsOutsideAliasRegion(VAddr address, size_t size) const {
+ return m_alias_region_start > address || address + size - 1 > m_alias_region_end - 1;
}
- constexpr bool IsOutsideStackRegion(VAddr address, std::size_t size) const {
- return stack_region_start > address || address + size - 1 > stack_region_end - 1;
+ constexpr bool IsOutsideStackRegion(VAddr address, size_t size) const {
+ return m_stack_region_start > address || address + size - 1 > m_stack_region_end - 1;
}
- constexpr bool IsInvalidRegion(VAddr address, std::size_t size) const {
+ constexpr bool IsInvalidRegion(VAddr address, size_t size) const {
return address + size - 1 > GetAliasCodeRegionStart() + GetAliasCodeRegionSize() - 1;
}
- constexpr bool IsInsideHeapRegion(VAddr address, std::size_t size) const {
- return address + size > heap_region_start && heap_region_end > address;
+ constexpr bool IsInsideHeapRegion(VAddr address, size_t size) const {
+ return address + size > m_heap_region_start && m_heap_region_end > address;
}
- constexpr bool IsInsideAliasRegion(VAddr address, std::size_t size) const {
- return address + size > alias_region_start && alias_region_end > address;
+ constexpr bool IsInsideAliasRegion(VAddr address, size_t size) const {
+ return address + size > m_alias_region_start && m_alias_region_end > address;
}
- constexpr bool IsOutsideASLRRegion(VAddr address, std::size_t size) const {
+ constexpr bool IsOutsideASLRRegion(VAddr address, size_t size) const {
if (IsInvalidRegion(address, size)) {
return true;
}
@@ -291,73 +297,78 @@ public:
}
return {};
}
- constexpr bool IsInsideASLRRegion(VAddr address, std::size_t size) const {
+ constexpr bool IsInsideASLRRegion(VAddr address, size_t size) const {
return !IsOutsideASLRRegion(address, size);
}
- constexpr std::size_t GetNumGuardPages() const {
+ constexpr size_t GetNumGuardPages() const {
return IsKernel() ? 1 : 4;
}
PAddr GetPhysicalAddr(VAddr addr) const {
- const auto backing_addr = page_table_impl.backing_addr[addr >> PageBits];
+ const auto backing_addr = m_page_table_impl->backing_addr[addr >> PageBits];
ASSERT(backing_addr);
return backing_addr + addr;
}
constexpr bool Contains(VAddr addr) const {
- return address_space_start <= addr && addr <= address_space_end - 1;
+ return m_address_space_start <= addr && addr <= m_address_space_end - 1;
}
- constexpr bool Contains(VAddr addr, std::size_t size) const {
- return address_space_start <= addr && addr < addr + size &&
- addr + size - 1 <= address_space_end - 1;
+ constexpr bool Contains(VAddr addr, size_t size) const {
+ return m_address_space_start <= addr && addr < addr + size &&
+ addr + size - 1 <= m_address_space_end - 1;
}
private:
constexpr bool IsKernel() const {
- return is_kernel;
+ return m_is_kernel;
}
constexpr bool IsAslrEnabled() const {
- return is_aslr_enabled;
+ return m_enable_aslr;
}
- constexpr bool ContainsPages(VAddr addr, std::size_t num_pages) const {
- return (address_space_start <= addr) &&
- (num_pages <= (address_space_end - address_space_start) / PageSize) &&
- (addr + num_pages * PageSize - 1 <= address_space_end - 1);
+ constexpr bool ContainsPages(VAddr addr, size_t num_pages) const {
+ return (m_address_space_start <= addr) &&
+ (num_pages <= (m_address_space_end - m_address_space_start) / PageSize) &&
+ (addr + num_pages * PageSize - 1 <= m_address_space_end - 1);
}
private:
- VAddr address_space_start{};
- VAddr address_space_end{};
- VAddr heap_region_start{};
- VAddr heap_region_end{};
- VAddr current_heap_end{};
- VAddr alias_region_start{};
- VAddr alias_region_end{};
- VAddr stack_region_start{};
- VAddr stack_region_end{};
- VAddr kernel_map_region_start{};
- VAddr kernel_map_region_end{};
- VAddr code_region_start{};
- VAddr code_region_end{};
- VAddr alias_code_region_start{};
- VAddr alias_code_region_end{};
-
- std::size_t mapped_physical_memory_size{};
- std::size_t max_heap_size{};
- std::size_t max_physical_memory_size{};
- std::size_t address_space_width{};
-
- bool is_kernel{};
- bool is_aslr_enabled{};
-
- u32 heap_fill_value{};
- const KMemoryRegion* cached_physical_heap_region{};
-
- KMemoryManager::Pool memory_pool{KMemoryManager::Pool::Application};
- KMemoryManager::Direction allocation_option{KMemoryManager::Direction::FromFront};
-
- Common::PageTable page_table_impl;
-
- Core::System& system;
+ VAddr m_address_space_start{};
+ VAddr m_address_space_end{};
+ VAddr m_heap_region_start{};
+ VAddr m_heap_region_end{};
+ VAddr m_current_heap_end{};
+ VAddr m_alias_region_start{};
+ VAddr m_alias_region_end{};
+ VAddr m_stack_region_start{};
+ VAddr m_stack_region_end{};
+ VAddr m_kernel_map_region_start{};
+ VAddr m_kernel_map_region_end{};
+ VAddr m_code_region_start{};
+ VAddr m_code_region_end{};
+ VAddr m_alias_code_region_start{};
+ VAddr m_alias_code_region_end{};
+
+ size_t m_mapped_physical_memory_size{};
+ size_t m_max_heap_size{};
+ size_t m_max_physical_memory_size{};
+ size_t m_address_space_width{};
+
+ KMemoryBlockManager m_memory_block_manager;
+
+ bool m_is_kernel{};
+ bool m_enable_aslr{};
+ bool m_enable_device_address_space_merge{};
+
+ KMemoryBlockSlabManager* m_memory_block_slab_manager{};
+
+ u32 m_heap_fill_value{};
+ const KMemoryRegion* m_cached_physical_heap_region{};
+
+ KMemoryManager::Pool m_memory_pool{KMemoryManager::Pool::Application};
+ KMemoryManager::Direction m_allocation_option{KMemoryManager::Direction::FromFront};
+
+ std::unique_ptr<Common::PageTable> m_page_table_impl;
+
+ Core::System& m_system;
};
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_port.cpp b/src/core/hle/kernel/k_port.cpp
index 7a5a9dc2a..77d00ae2c 100644
--- a/src/core/hle/kernel/k_port.cpp
+++ b/src/core/hle/kernel/k_port.cpp
@@ -57,12 +57,6 @@ Result KPort::EnqueueSession(KServerSession* session) {
server.EnqueueSession(session);
- if (auto session_ptr = server.GetSessionRequestHandler().lock()) {
- session_ptr->ClientConnected(server.AcceptSession());
- } else {
- ASSERT(false);
- }
-
return ResultSuccess;
}
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index d3e99665f..8c3495e5a 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -72,7 +72,8 @@ Result KProcess::Initialize(KProcess* process, Core::System& system, std::string
process->name = std::move(process_name);
process->resource_limit = res_limit;
- process->status = ProcessStatus::Created;
+ process->system_resource_address = 0;
+ process->state = State::Created;
process->program_id = 0;
process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
: kernel.CreateNewUserProcessID();
@@ -92,11 +93,12 @@ Result KProcess::Initialize(KProcess* process, Core::System& system, std::string
process->exception_thread = nullptr;
process->is_suspended = false;
process->schedule_count = 0;
+ process->is_handle_table_initialized = false;
// Open a reference to the resource limit.
process->resource_limit->Open();
- return ResultSuccess;
+ R_SUCCEED();
}
void KProcess::DoWorkerTaskImpl() {
@@ -121,9 +123,9 @@ void KProcess::DecrementRunningThreadCount() {
}
}
-u64 KProcess::GetTotalPhysicalMemoryAvailable() const {
+u64 KProcess::GetTotalPhysicalMemoryAvailable() {
const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) +
- page_table->GetNormalMemorySize() + GetSystemResourceSize() + image_size +
+ page_table.GetNormalMemorySize() + GetSystemResourceSize() + image_size +
main_thread_stack_size};
if (const auto pool_size = kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application);
capacity != pool_size) {
@@ -135,16 +137,16 @@ u64 KProcess::GetTotalPhysicalMemoryAvailable() const {
return memory_usage_capacity;
}
-u64 KProcess::GetTotalPhysicalMemoryAvailableWithoutSystemResource() const {
+u64 KProcess::GetTotalPhysicalMemoryAvailableWithoutSystemResource() {
return GetTotalPhysicalMemoryAvailable() - GetSystemResourceSize();
}
-u64 KProcess::GetTotalPhysicalMemoryUsed() const {
- return image_size + main_thread_stack_size + page_table->GetNormalMemorySize() +
+u64 KProcess::GetTotalPhysicalMemoryUsed() {
+ return image_size + main_thread_stack_size + page_table.GetNormalMemorySize() +
GetSystemResourceSize();
}
-u64 KProcess::GetTotalPhysicalMemoryUsedWithoutSystemResource() const {
+u64 KProcess::GetTotalPhysicalMemoryUsedWithoutSystemResource() {
return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage();
}
@@ -244,7 +246,7 @@ Result KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr ad
shmem->Open();
shemen_info->Open();
- return ResultSuccess;
+ R_SUCCEED();
}
void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr address,
@@ -289,12 +291,12 @@ Result KProcess::Reset() {
KScopedSchedulerLock sl{kernel};
// Validate that we're in a state that we can reset.
- R_UNLESS(status != ProcessStatus::Exited, ResultInvalidState);
+ R_UNLESS(state != State::Terminated, ResultInvalidState);
R_UNLESS(is_signaled, ResultInvalidState);
// Clear signaled.
is_signaled = false;
- return ResultSuccess;
+ R_SUCCEED();
}
Result KProcess::SetActivity(ProcessActivity activity) {
@@ -304,15 +306,13 @@ Result KProcess::SetActivity(ProcessActivity activity) {
KScopedSchedulerLock sl{kernel};
// Validate our state.
- R_UNLESS(status != ProcessStatus::Exiting, ResultInvalidState);
- R_UNLESS(status != ProcessStatus::Exited, ResultInvalidState);
+ R_UNLESS(state != State::Terminating, ResultInvalidState);
+ R_UNLESS(state != State::Terminated, ResultInvalidState);
// Either pause or resume.
if (activity == ProcessActivity::Paused) {
// Verify that we're not suspended.
- if (is_suspended) {
- return ResultInvalidState;
- }
+ R_UNLESS(!is_suspended, ResultInvalidState);
// Suspend all threads.
for (auto* thread : GetThreadList()) {
@@ -325,9 +325,7 @@ Result KProcess::SetActivity(ProcessActivity activity) {
ASSERT(activity == ProcessActivity::Runnable);
// Verify that we're suspended.
- if (!is_suspended) {
- return ResultInvalidState;
- }
+ R_UNLESS(is_suspended, ResultInvalidState);
// Resume all threads.
for (auto* thread : GetThreadList()) {
@@ -338,7 +336,7 @@ Result KProcess::SetActivity(ProcessActivity activity) {
SetSuspended(false);
}
- return ResultSuccess;
+ R_SUCCEED();
}
Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size) {
@@ -348,35 +346,38 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
system_resource_size = metadata.GetSystemResourceSize();
image_size = code_size;
+ // We currently do not support process-specific system resource
+ UNIMPLEMENTED_IF(system_resource_size != 0);
+
KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory,
code_size + system_resource_size);
if (!memory_reservation.Succeeded()) {
LOG_ERROR(Kernel, "Could not reserve process memory requirements of size {:X} bytes",
code_size + system_resource_size);
- return ResultLimitReached;
+ R_RETURN(ResultLimitReached);
}
// Initialize proces address space
- if (const Result result{page_table->InitializeForProcess(metadata.GetAddressSpaceType(), false,
- 0x8000000, code_size,
- KMemoryManager::Pool::Application)};
+ if (const Result result{page_table.InitializeForProcess(
+ metadata.GetAddressSpaceType(), false, 0x8000000, code_size,
+ &kernel.GetApplicationMemoryBlockManager(), KMemoryManager::Pool::Application)};
result.IsError()) {
- return result;
+ R_RETURN(result);
}
// Map process code region
- if (const Result result{page_table->MapProcessCode(page_table->GetCodeRegionStart(),
- code_size / PageSize, KMemoryState::Code,
- KMemoryPermission::None)};
+ if (const Result result{page_table.MapProcessCode(page_table.GetCodeRegionStart(),
+ code_size / PageSize, KMemoryState::Code,
+ KMemoryPermission::None)};
result.IsError()) {
- return result;
+ R_RETURN(result);
}
// Initialize process capabilities
const auto& caps{metadata.GetKernelCapabilities()};
if (const Result result{
- capabilities.InitializeForUserProcess(caps.data(), caps.size(), *page_table)};
+ capabilities.InitializeForUserProcess(caps.data(), caps.size(), page_table)};
result.IsError()) {
- return result;
+ R_RETURN(result);
}
// Set memory usage capacity
@@ -384,12 +385,12 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
case FileSys::ProgramAddressSpaceType::Is32Bit:
case FileSys::ProgramAddressSpaceType::Is36Bit:
case FileSys::ProgramAddressSpaceType::Is39Bit:
- memory_usage_capacity = page_table->GetHeapRegionEnd() - page_table->GetHeapRegionStart();
+ memory_usage_capacity = page_table.GetHeapRegionEnd() - page_table.GetHeapRegionStart();
break;
case FileSys::ProgramAddressSpaceType::Is32BitNoMap:
- memory_usage_capacity = page_table->GetHeapRegionEnd() - page_table->GetHeapRegionStart() +
- page_table->GetAliasRegionEnd() - page_table->GetAliasRegionStart();
+ memory_usage_capacity = page_table.GetHeapRegionEnd() - page_table.GetHeapRegionStart() +
+ page_table.GetAliasRegionEnd() - page_table.GetAliasRegionStart();
break;
default:
@@ -397,10 +398,10 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
}
// Create TLS region
- R_TRY(this->CreateThreadLocalRegion(std::addressof(tls_region_address)));
+ R_TRY(this->CreateThreadLocalRegion(std::addressof(plr_address)));
memory_reservation.Commit();
- return handle_table.Initialize(capabilities.GetHandleTableSize());
+ R_RETURN(handle_table.Initialize(capabilities.GetHandleTableSize()));
}
void KProcess::Run(s32 main_thread_priority, u64 stack_size) {
@@ -409,15 +410,15 @@ void KProcess::Run(s32 main_thread_priority, u64 stack_size) {
resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size);
const std::size_t heap_capacity{memory_usage_capacity - (main_thread_stack_size + image_size)};
- ASSERT(!page_table->SetMaxHeapSize(heap_capacity).IsError());
+ ASSERT(!page_table.SetMaxHeapSize(heap_capacity).IsError());
- ChangeStatus(ProcessStatus::Running);
+ ChangeState(State::Running);
SetupMainThread(kernel.System(), *this, main_thread_priority, main_thread_stack_top);
}
void KProcess::PrepareForTermination() {
- ChangeStatus(ProcessStatus::Exiting);
+ ChangeState(State::Terminating);
const auto stop_threads = [this](const std::vector<KThread*>& in_thread_list) {
for (auto* thread : in_thread_list) {
@@ -437,15 +438,15 @@ void KProcess::PrepareForTermination() {
stop_threads(kernel.System().GlobalSchedulerContext().GetThreadList());
- this->DeleteThreadLocalRegion(tls_region_address);
- tls_region_address = 0;
+ this->DeleteThreadLocalRegion(plr_address);
+ plr_address = 0;
if (resource_limit) {
resource_limit->Release(LimitableResource::PhysicalMemory,
main_thread_stack_size + image_size);
}
- ChangeStatus(ProcessStatus::Exited);
+ ChangeState(State::Terminated);
}
void KProcess::Finalize() {
@@ -474,7 +475,7 @@ void KProcess::Finalize() {
}
// Finalize the page table.
- page_table.reset();
+ page_table.Finalize();
// Perform inherited finalization.
KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask>::Finalize();
@@ -499,7 +500,7 @@ Result KProcess::CreateThreadLocalRegion(VAddr* out) {
}
*out = tlr;
- return ResultSuccess;
+ R_SUCCEED();
}
}
@@ -528,7 +529,7 @@ Result KProcess::CreateThreadLocalRegion(VAddr* out) {
// We succeeded!
tlp_guard.Cancel();
*out = tlr;
- return ResultSuccess;
+ R_SUCCEED();
}
Result KProcess::DeleteThreadLocalRegion(VAddr addr) {
@@ -576,7 +577,7 @@ Result KProcess::DeleteThreadLocalRegion(VAddr addr) {
KThreadLocalPage::Free(kernel, page_to_free);
}
- return ResultSuccess;
+ R_SUCCEED();
}
bool KProcess::InsertWatchpoint(Core::System& system, VAddr addr, u64 size,
@@ -628,7 +629,7 @@ bool KProcess::RemoveWatchpoint(Core::System& system, VAddr addr, u64 size,
void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) {
const auto ReprotectSegment = [&](const CodeSet::Segment& segment,
Svc::MemoryPermission permission) {
- page_table->SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission);
+ page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission);
};
kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(),
@@ -645,19 +646,18 @@ bool KProcess::IsSignaled() const {
}
KProcess::KProcess(KernelCore& kernel_)
- : KAutoObjectWithSlabHeapAndContainer{kernel_}, page_table{std::make_unique<KPageTable>(
- kernel_.System())},
+ : KAutoObjectWithSlabHeapAndContainer{kernel_}, page_table{kernel_.System()},
handle_table{kernel_}, address_arbiter{kernel_.System()}, condition_var{kernel_.System()},
state_lock{kernel_}, list_lock{kernel_} {}
KProcess::~KProcess() = default;
-void KProcess::ChangeStatus(ProcessStatus new_status) {
- if (status == new_status) {
+void KProcess::ChangeState(State new_state) {
+ if (state == new_state) {
return;
}
- status = new_status;
+ state = new_state;
is_signaled = true;
NotifyAvailable();
}
@@ -668,17 +668,17 @@ Result KProcess::AllocateMainThreadStack(std::size_t stack_size) {
// The kernel always ensures that the given stack size is page aligned.
main_thread_stack_size = Common::AlignUp(stack_size, PageSize);
- const VAddr start{page_table->GetStackRegionStart()};
- const std::size_t size{page_table->GetStackRegionEnd() - start};
+ const VAddr start{page_table.GetStackRegionStart()};
+ const std::size_t size{page_table.GetStackRegionEnd() - start};
CASCADE_RESULT(main_thread_stack_top,
- page_table->AllocateAndMapMemory(
+ page_table.AllocateAndMapMemory(
main_thread_stack_size / PageSize, PageSize, false, start, size / PageSize,
KMemoryState::Stack, KMemoryPermission::UserReadWrite));
main_thread_stack_top += main_thread_stack_size;
- return ResultSuccess;
+ R_SUCCEED();
}
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index d56d73bab..2e0cc3d0b 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -13,6 +13,7 @@
#include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/k_condition_variable.h"
#include "core/hle/kernel/k_handle_table.h"
+#include "core/hle/kernel/k_page_table.h"
#include "core/hle/kernel/k_synchronization_object.h"
#include "core/hle/kernel/k_thread_local_page.h"
#include "core/hle/kernel/k_worker_task.h"
@@ -31,7 +32,6 @@ class ProgramMetadata;
namespace Kernel {
class KernelCore;
-class KPageTable;
class KResourceLimit;
class KThread;
class KSharedMemoryInfo;
@@ -45,24 +45,6 @@ enum class MemoryRegion : u16 {
BASE = 3,
};
-/**
- * Indicates the status of a Process instance.
- *
- * @note These match the values as used by kernel,
- * so new entries should only be added if RE
- * shows that a new value has been introduced.
- */
-enum class ProcessStatus {
- Created,
- CreatedWithDebuggerAttached,
- Running,
- WaitingForDebuggerToAttach,
- DebuggerAttached,
- Exiting,
- Exited,
- DebugBreak,
-};
-
enum class ProcessActivity : u32 {
Runnable,
Paused,
@@ -89,6 +71,17 @@ public:
explicit KProcess(KernelCore& kernel_);
~KProcess() override;
+ enum class State {
+ Created = static_cast<u32>(Svc::ProcessState::Created),
+ CreatedAttached = static_cast<u32>(Svc::ProcessState::CreatedAttached),
+ Running = static_cast<u32>(Svc::ProcessState::Running),
+ Crashed = static_cast<u32>(Svc::ProcessState::Crashed),
+ RunningAttached = static_cast<u32>(Svc::ProcessState::RunningAttached),
+ Terminating = static_cast<u32>(Svc::ProcessState::Terminating),
+ Terminated = static_cast<u32>(Svc::ProcessState::Terminated),
+ DebugBreak = static_cast<u32>(Svc::ProcessState::DebugBreak),
+ };
+
enum : u64 {
/// Lowest allowed process ID for a kernel initial process.
InitialKIPIDMin = 1,
@@ -114,12 +107,12 @@ public:
/// Gets a reference to the process' page table.
KPageTable& PageTable() {
- return *page_table;
+ return page_table;
}
/// Gets const a reference to the process' page table.
const KPageTable& PageTable() const {
- return *page_table;
+ return page_table;
}
/// Gets a reference to the process' handle table.
@@ -145,26 +138,25 @@ public:
}
Result WaitConditionVariable(VAddr address, u64 cv_key, u32 tag, s64 ns) {
- return condition_var.Wait(address, cv_key, tag, ns);
+ R_RETURN(condition_var.Wait(address, cv_key, tag, ns));
}
Result SignalAddressArbiter(VAddr address, Svc::SignalType signal_type, s32 value, s32 count) {
- return address_arbiter.SignalToAddress(address, signal_type, value, count);
+ R_RETURN(address_arbiter.SignalToAddress(address, signal_type, value, count));
}
Result WaitAddressArbiter(VAddr address, Svc::ArbitrationType arb_type, s32 value,
s64 timeout) {
- return address_arbiter.WaitForAddress(address, arb_type, value, timeout);
+ R_RETURN(address_arbiter.WaitForAddress(address, arb_type, value, timeout));
}
- /// Gets the address to the process' dedicated TLS region.
- VAddr GetTLSRegionAddress() const {
- return tls_region_address;
+ VAddr GetProcessLocalRegionAddress() const {
+ return plr_address;
}
/// Gets the current status of the process
- ProcessStatus GetStatus() const {
- return status;
+ State GetState() const {
+ return state;
}
/// Gets the unique ID that identifies this particular process.
@@ -286,18 +278,18 @@ public:
}
/// Retrieves the total physical memory available to this process in bytes.
- u64 GetTotalPhysicalMemoryAvailable() const;
+ u64 GetTotalPhysicalMemoryAvailable();
/// Retrieves the total physical memory available to this process in bytes,
/// without the size of the personal system resource heap added to it.
- u64 GetTotalPhysicalMemoryAvailableWithoutSystemResource() const;
+ u64 GetTotalPhysicalMemoryAvailableWithoutSystemResource();
/// Retrieves the total physical memory used by this process in bytes.
- u64 GetTotalPhysicalMemoryUsed() const;
+ u64 GetTotalPhysicalMemoryUsed();
/// Retrieves the total physical memory used by this process in bytes,
/// without the size of the personal system resource heap added to it.
- u64 GetTotalPhysicalMemoryUsedWithoutSystemResource() const;
+ u64 GetTotalPhysicalMemoryUsedWithoutSystemResource();
/// Gets the list of all threads created with this process as their owner.
std::list<KThread*>& GetThreadList() {
@@ -415,19 +407,24 @@ private:
pinned_threads[core_id] = nullptr;
}
- /// Changes the process status. If the status is different
- /// from the current process status, then this will trigger
- /// a process signal.
- void ChangeStatus(ProcessStatus new_status);
+ void FinalizeHandleTable() {
+ // Finalize the table.
+ handle_table.Finalize();
+
+ // Note that the table is finalized.
+ is_handle_table_initialized = false;
+ }
+
+ void ChangeState(State new_state);
/// Allocates the main thread stack for the process, given the stack size in bytes.
Result AllocateMainThreadStack(std::size_t stack_size);
/// Memory manager for this process
- std::unique_ptr<KPageTable> page_table;
+ KPageTable page_table;
/// Current status of the process
- ProcessStatus status{};
+ State state{};
/// The ID of this process
u64 process_id = 0;
@@ -443,6 +440,8 @@ private:
/// Resource limit descriptor for this process
KResourceLimit* resource_limit{};
+ VAddr system_resource_address{};
+
/// The ideal CPU core for this process, threads are scheduled on this core by default.
u8 ideal_core = 0;
@@ -469,7 +468,7 @@ private:
KConditionVariable condition_var;
/// Address indicating the location of the process' dedicated TLS region.
- VAddr tls_region_address = 0;
+ VAddr plr_address = 0;
/// Random values for svcGetInfo RandomEntropy
std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy{};
@@ -495,8 +494,12 @@ private:
/// Schedule count of this process
s64 schedule_count{};
+ size_t memory_release_hint{};
+
bool is_signaled{};
bool is_suspended{};
+ bool is_immortal{};
+ bool is_handle_table_initialized{};
bool is_initialized{};
std::atomic<u16> num_running_threads{};
diff --git a/src/core/hle/kernel/k_readable_event.cpp b/src/core/hle/kernel/k_readable_event.cpp
index 94c5464fe..5c942d47c 100644
--- a/src/core/hle/kernel/k_readable_event.cpp
+++ b/src/core/hle/kernel/k_readable_event.cpp
@@ -15,31 +15,44 @@ KReadableEvent::KReadableEvent(KernelCore& kernel_) : KSynchronizationObject{ker
KReadableEvent::~KReadableEvent() = default;
+void KReadableEvent::Initialize(KEvent* parent) {
+ m_is_signaled = false;
+ m_parent = parent;
+
+ if (m_parent != nullptr) {
+ m_parent->Open();
+ }
+}
+
bool KReadableEvent::IsSignaled() const {
- ASSERT(kernel.GlobalSchedulerContext().IsLocked());
+ ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
- return is_signaled;
+ return m_is_signaled;
}
void KReadableEvent::Destroy() {
- if (parent) {
- parent->Close();
+ if (m_parent) {
+ {
+ KScopedSchedulerLock sl{kernel};
+ m_parent->OnReadableEventDestroyed();
+ }
+ m_parent->Close();
}
}
Result KReadableEvent::Signal() {
KScopedSchedulerLock lk{kernel};
- if (!is_signaled) {
- is_signaled = true;
- NotifyAvailable();
+ if (!m_is_signaled) {
+ m_is_signaled = true;
+ this->NotifyAvailable();
}
return ResultSuccess;
}
Result KReadableEvent::Clear() {
- Reset();
+ this->Reset();
return ResultSuccess;
}
@@ -47,11 +60,11 @@ Result KReadableEvent::Clear() {
Result KReadableEvent::Reset() {
KScopedSchedulerLock lk{kernel};
- if (!is_signaled) {
+ if (!m_is_signaled) {
return ResultInvalidState;
}
- is_signaled = false;
+ m_is_signaled = false;
return ResultSuccess;
}
diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h
index 18dcad289..743f96bf5 100644
--- a/src/core/hle/kernel/k_readable_event.h
+++ b/src/core/hle/kernel/k_readable_event.h
@@ -20,26 +20,23 @@ public:
explicit KReadableEvent(KernelCore& kernel_);
~KReadableEvent() override;
- void Initialize(KEvent* parent_event_, std::string&& name_) {
- is_signaled = false;
- parent = parent_event_;
- name = std::move(name_);
- }
+ void Initialize(KEvent* parent);
KEvent* GetParent() const {
- return parent;
+ return m_parent;
}
+ Result Signal();
+ Result Clear();
+
bool IsSignaled() const override;
void Destroy() override;
- Result Signal();
- Result Clear();
Result Reset();
private:
- bool is_signaled{};
- KEvent* parent{};
+ bool m_is_signaled{};
+ KEvent* m_parent{};
};
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp
index c34ce7a17..b1cabbca0 100644
--- a/src/core/hle/kernel/k_scheduler.cpp
+++ b/src/core/hle/kernel/k_scheduler.cpp
@@ -81,8 +81,8 @@ void KScheduler::RescheduleCurrentHLEThread(KernelCore& kernel) {
// HACK: we cannot schedule from this thread, it is not a core thread
ASSERT(GetCurrentThread(kernel).GetDisableDispatchCount() == 1);
- // Special case to ensure dummy threads that are waiting block
- GetCurrentThread(kernel).IfDummyThreadTryWait();
+ // Ensure dummy threads that are waiting block.
+ GetCurrentThread(kernel).DummyThreadBeginWait();
ASSERT(GetCurrentThread(kernel).GetState() != ThreadState::Waiting);
GetCurrentThread(kernel).EnableDispatch();
@@ -314,6 +314,16 @@ u64 KScheduler::UpdateHighestPriorityThreadsImpl(KernelCore& kernel) {
idle_cores &= ~(1ULL << core_id);
}
+ // HACK: any waiting dummy threads can wake up now.
+ kernel.GlobalSchedulerContext().WakeupWaitingDummyThreads();
+
+ // HACK: if we are a dummy thread, and we need to go sleep, indicate
+ // that for when the lock is released.
+ KThread* const cur_thread = GetCurrentThreadPointer(kernel);
+ if (cur_thread->IsDummyThread() && cur_thread->GetState() != ThreadState::Runnable) {
+ cur_thread->RequestDummyThreadWait();
+ }
+
return cores_needing_scheduling;
}
@@ -531,11 +541,23 @@ void KScheduler::OnThreadStateChanged(KernelCore& kernel, KThread* thread, Threa
GetPriorityQueue(kernel).Remove(thread);
IncrementScheduledCount(thread);
SetSchedulerUpdateNeeded(kernel);
+
+ if (thread->IsDummyThread()) {
+ // HACK: if this is a dummy thread, it should no longer wake up when the
+ // scheduler lock is released.
+ kernel.GlobalSchedulerContext().UnregisterDummyThreadForWakeup(thread);
+ }
} else if (cur_state == ThreadState::Runnable) {
// If we're now runnable, then we weren't previously, and we should add.
GetPriorityQueue(kernel).PushBack(thread);
IncrementScheduledCount(thread);
SetSchedulerUpdateNeeded(kernel);
+
+ if (thread->IsDummyThread()) {
+ // HACK: if this is a dummy thread, it should wake up when the scheduler
+ // lock is released.
+ kernel.GlobalSchedulerContext().RegisterDummyThreadForWakeup(thread);
+ }
}
}
diff --git a/src/core/hle/kernel/k_server_port.cpp b/src/core/hle/kernel/k_server_port.cpp
index e968f26ad..16968ba97 100644
--- a/src/core/hle/kernel/k_server_port.cpp
+++ b/src/core/hle/kernel/k_server_port.cpp
@@ -61,12 +61,6 @@ void KServerPort::Destroy() {
// Close our reference to our parent.
parent->Close();
-
- // Release host emulation members.
- session_handler.reset();
-
- // Ensure that the global list tracking server objects does not hold on to a reference.
- kernel.UnregisterServerObject(this);
}
bool KServerPort::IsSignaled() const {
diff --git a/src/core/hle/kernel/k_server_port.h b/src/core/hle/kernel/k_server_port.h
index fd4f4bd20..5fc7ee683 100644
--- a/src/core/hle/kernel/k_server_port.h
+++ b/src/core/hle/kernel/k_server_port.h
@@ -27,24 +27,6 @@ public:
void Initialize(KPort* parent_port_, std::string&& name_);
- /// Whether or not this server port has an HLE handler available.
- bool HasSessionRequestHandler() const {
- return !session_handler.expired();
- }
-
- /// Gets the HLE handler for this port.
- SessionRequestHandlerWeakPtr GetSessionRequestHandler() const {
- return session_handler;
- }
-
- /**
- * Sets the HLE handler template for the port. ServerSessions crated by connecting to this port
- * will inherit a reference to this handler.
- */
- void SetSessionHandler(SessionRequestHandlerWeakPtr&& handler) {
- session_handler = std::move(handler);
- }
-
void EnqueueSession(KServerSession* pending_session);
KServerSession* AcceptSession();
@@ -65,7 +47,6 @@ private:
void CleanupSessions();
SessionList session_list;
- SessionRequestHandlerWeakPtr session_handler;
KPort* parent{};
};
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp
index 802c646a6..aa1941f01 100644
--- a/src/core/hle/kernel/k_server_session.cpp
+++ b/src/core/hle/kernel/k_server_session.cpp
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <tuple>
@@ -7,6 +7,8 @@
#include "common/assert.h"
#include "common/common_types.h"
#include "common/logging/log.h"
+#include "common/scope_exit.h"
+#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/hle_ipc.h"
@@ -18,49 +20,128 @@
#include "core/hle/kernel/k_server_session.h"
#include "core/hle/kernel/k_session.h"
#include "core/hle/kernel/k_thread.h"
+#include "core/hle/kernel/k_thread_queue.h"
#include "core/hle/kernel/kernel.h"
-#include "core/hle/kernel/service_thread.h"
#include "core/memory.h"
namespace Kernel {
-KServerSession::KServerSession(KernelCore& kernel_) : KSynchronizationObject{kernel_} {}
+using ThreadQueueImplForKServerSessionRequest = KThreadQueue;
+
+KServerSession::KServerSession(KernelCore& kernel_)
+ : KSynchronizationObject{kernel_}, m_lock{kernel_} {}
KServerSession::~KServerSession() = default;
-void KServerSession::Initialize(KSession* parent_session_, std::string&& name_,
- std::shared_ptr<SessionRequestManager> manager_) {
+void KServerSession::Initialize(KSession* parent_session_, std::string&& name_) {
// Set member variables.
parent = parent_session_;
name = std::move(name_);
-
- if (manager_) {
- manager = manager_;
- } else {
- manager = std::make_shared<SessionRequestManager>(kernel);
- }
}
void KServerSession::Destroy() {
parent->OnServerClosed();
- parent->Close();
+ this->CleanupRequests();
- // Release host emulation members.
- manager.reset();
-
- // Ensure that the global list tracking server objects does not hold on to a reference.
- kernel.UnregisterServerObject(this);
+ parent->Close();
}
void KServerSession::OnClientClosed() {
- if (manager->HasSessionHandler()) {
- manager->SessionHandler().ClientDisconnected(this);
+ KScopedLightLock lk{m_lock};
+
+ // Handle any pending requests.
+ KSessionRequest* prev_request = nullptr;
+ while (true) {
+ // Declare variables for processing the request.
+ KSessionRequest* request = nullptr;
+ KEvent* event = nullptr;
+ KThread* thread = nullptr;
+ bool cur_request = false;
+ bool terminate = false;
+
+ // Get the next request.
+ {
+ KScopedSchedulerLock sl{kernel};
+
+ if (m_current_request != nullptr && m_current_request != prev_request) {
+ // Set the request, open a reference as we process it.
+ request = m_current_request;
+ request->Open();
+ cur_request = true;
+
+ // Get thread and event for the request.
+ thread = request->GetThread();
+ event = request->GetEvent();
+
+ // If the thread is terminating, handle that.
+ if (thread->IsTerminationRequested()) {
+ request->ClearThread();
+ request->ClearEvent();
+ terminate = true;
+ }
+
+ prev_request = request;
+ } else if (!m_request_list.empty()) {
+ // Pop the request from the front of the list.
+ request = std::addressof(m_request_list.front());
+ m_request_list.pop_front();
+
+ // Get thread and event for the request.
+ thread = request->GetThread();
+ event = request->GetEvent();
+ }
+ }
+
+ // If there are no requests, we're done.
+ if (request == nullptr) {
+ break;
+ }
+
+ // All requests must have threads.
+ ASSERT(thread != nullptr);
+
+ // Ensure that we close the request when done.
+ SCOPE_EXIT({ request->Close(); });
+
+ // If we're terminating, close a reference to the thread and event.
+ if (terminate) {
+ thread->Close();
+ if (event != nullptr) {
+ event->Close();
+ }
+ }
+
+ // If we need to, reply.
+ if (event != nullptr && !cur_request) {
+ // There must be no mappings.
+ ASSERT(request->GetSendCount() == 0);
+ ASSERT(request->GetReceiveCount() == 0);
+ ASSERT(request->GetExchangeCount() == 0);
+
+ // // Get the process and page table.
+ // KProcess *client_process = thread->GetOwnerProcess();
+ // auto &client_pt = client_process->GetPageTable();
+
+ // // Reply to the request.
+ // ReplyAsyncError(client_process, request->GetAddress(), request->GetSize(),
+ // ResultSessionClosed);
+
+ // // Unlock the buffer.
+ // // NOTE: Nintendo does not check the result of this.
+ // client_pt.UnlockForIpcUserBuffer(request->GetAddress(), request->GetSize());
+
+ // Signal the event.
+ event->Signal();
+ }
}
+
+ // Notify.
+ this->NotifyAvailable(ResultSessionClosed);
}
bool KServerSession::IsSignaled() const {
- ASSERT(kernel.GlobalSchedulerContext().IsLocked());
+ ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
// If the client is closed, we're always signaled.
if (parent->IsClientClosed()) {
@@ -68,114 +149,271 @@ bool KServerSession::IsSignaled() const {
}
// Otherwise, we're signaled if we have a request and aren't handling one.
- return false;
+ return !m_request_list.empty() && m_current_request == nullptr;
}
-void KServerSession::AppendDomainHandler(SessionRequestHandlerPtr handler) {
- manager->AppendDomainHandler(std::move(handler));
-}
+Result KServerSession::OnRequest(KSessionRequest* request) {
+ // Create the wait queue.
+ ThreadQueueImplForKServerSessionRequest wait_queue{kernel};
-std::size_t KServerSession::NumDomainRequestHandlers() const {
- return manager->DomainHandlerCount();
-}
+ {
+ // Lock the scheduler.
+ KScopedSchedulerLock sl{kernel};
-Result KServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) {
- if (!context.HasDomainMessageHeader()) {
- return ResultSuccess;
- }
+ // Ensure that we can handle new requests.
+ R_UNLESS(!parent->IsServerClosed(), ResultSessionClosed);
- // Set domain handlers in HLE context, used for domain objects (IPC interfaces) as inputs
- context.SetSessionRequestManager(manager);
-
- // If there is a DomainMessageHeader, then this is CommandType "Request"
- const auto& domain_message_header = context.GetDomainMessageHeader();
- const u32 object_id{domain_message_header.object_id};
- switch (domain_message_header.command) {
- case IPC::DomainMessageHeader::CommandType::SendMessage:
- if (object_id > manager->DomainHandlerCount()) {
- LOG_CRITICAL(IPC,
- "object_id {} is too big! This probably means a recent service call "
- "to {} needed to return a new interface!",
- object_id, name);
- ASSERT(false);
- return ResultSuccess; // Ignore error if asserts are off
- }
- if (auto strong_ptr = manager->DomainHandler(object_id - 1).lock()) {
- return strong_ptr->HandleSyncRequest(*this, context);
- } else {
- ASSERT(false);
- return ResultSuccess;
- }
+ // Check that we're not terminating.
+ R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(), ResultTerminationRequested);
- case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
- LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x{:08X}", object_id);
+ // Get whether we're empty.
+ const bool was_empty = m_request_list.empty();
- manager->CloseDomainHandler(object_id - 1);
+ // Add the request to the list.
+ request->Open();
+ m_request_list.push_back(*request);
- IPC::ResponseBuilder rb{context, 2};
- rb.Push(ResultSuccess);
- return ResultSuccess;
- }
+ // If we were empty, signal.
+ if (was_empty) {
+ this->NotifyAvailable();
+ }
+
+ // If we have a request event, this is asynchronous, and we don't need to wait.
+ R_SUCCEED_IF(request->GetEvent() != nullptr);
+
+ // This is a synchronous request, so we should wait for our request to complete.
+ GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
+ GetCurrentThread(kernel).BeginWait(&wait_queue);
}
- LOG_CRITICAL(IPC, "Unknown domain command={}", domain_message_header.command.Value());
- ASSERT(false);
- return ResultSuccess;
+ return GetCurrentThread(kernel).GetWaitResult();
}
-Result KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory) {
- u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(thread->GetTLSAddress()))};
- auto context = std::make_shared<HLERequestContext>(kernel, memory, this, thread);
+Result KServerSession::SendReply(bool is_hle) {
+ // Lock the session.
+ KScopedLightLock lk{m_lock};
- context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
+ // Get the request.
+ KSessionRequest* request;
+ {
+ KScopedSchedulerLock sl{kernel};
- // Ensure we have a session request handler
- if (manager->HasSessionRequestHandler(*context)) {
- if (auto strong_ptr = manager->GetServiceThread().lock()) {
- strong_ptr->QueueSyncRequest(*parent, std::move(context));
- } else {
- ASSERT_MSG(false, "strong_ptr is nullptr!");
+ // Get the current request.
+ request = m_current_request;
+ R_UNLESS(request != nullptr, ResultInvalidState);
+
+ // Clear the current request, since we're processing it.
+ m_current_request = nullptr;
+ if (!m_request_list.empty()) {
+ this->NotifyAvailable();
}
- } else {
- ASSERT_MSG(false, "handler is invalid!");
}
- return ResultSuccess;
-}
+ // Close reference to the request once we're done processing it.
+ SCOPE_EXIT({ request->Close(); });
+
+ // Extract relevant information from the request.
+ const uintptr_t client_message = request->GetAddress();
+ const size_t client_buffer_size = request->GetSize();
+ KThread* client_thread = request->GetThread();
+ KEvent* event = request->GetEvent();
+
+ // Check whether we're closed.
+ const bool closed = (client_thread == nullptr || parent->IsClientClosed());
-Result KServerSession::CompleteSyncRequest(HLERequestContext& context) {
Result result = ResultSuccess;
+ if (!closed) {
+ // If we're not closed, send the reply.
+ if (is_hle) {
+ // HLE servers write directly to a pointer to the thread command buffer. Therefore
+ // the reply has already been written in this case.
+ } else {
+ Core::Memory::Memory& memory{kernel.System().Memory()};
+ KThread* server_thread{GetCurrentThreadPointer(kernel)};
+ UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess());
- // If the session has been converted to a domain, handle the domain request
- if (manager->HasSessionRequestHandler(context)) {
- if (IsDomain() && context.HasDomainMessageHeader()) {
- result = HandleDomainSyncRequest(context);
- // If there is no domain header, the regular session handler is used
- } else if (manager->HasSessionHandler()) {
- // If this ServerSession has an associated HLE handler, forward the request to it.
- result = manager->SessionHandler().HandleSyncRequest(*this, context);
+ auto* src_msg_buffer = memory.GetPointer(server_thread->GetTLSAddress());
+ auto* dst_msg_buffer = memory.GetPointer(client_message);
+ std::memcpy(dst_msg_buffer, src_msg_buffer, client_buffer_size);
}
} else {
- ASSERT_MSG(false, "Session handler is invalid, stubbing response!");
- IPC::ResponseBuilder rb(context, 2);
- rb.Push(ResultSuccess);
+ result = ResultSessionClosed;
}
- if (convert_to_domain) {
- ASSERT_MSG(!IsDomain(), "ServerSession is already a domain instance.");
- manager->ConvertToDomain();
- convert_to_domain = false;
+ // Select a result for the client.
+ Result client_result = result;
+ if (closed && R_SUCCEEDED(result)) {
+ result = ResultSessionClosed;
+ client_result = ResultSessionClosed;
+ } else {
+ result = ResultSuccess;
}
- // The calling thread is waiting for this request to complete, so wake it up.
- context.GetThread().EndWait(result);
+ // If there's a client thread, update it.
+ if (client_thread != nullptr) {
+ if (event != nullptr) {
+ // // Get the client process/page table.
+ // KProcess *client_process = client_thread->GetOwnerProcess();
+ // KPageTable *client_page_table = &client_process->PageTable();
+
+ // // If we need to, reply with an async error.
+ // if (R_FAILED(client_result)) {
+ // ReplyAsyncError(client_process, client_message, client_buffer_size,
+ // client_result);
+ // }
+
+ // // Unlock the client buffer.
+ // // NOTE: Nintendo does not check the result of this.
+ // client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size);
+
+ // Signal the event.
+ event->Signal();
+ } else {
+ // End the client thread's wait.
+ KScopedSchedulerLock sl{kernel};
+
+ if (!client_thread->IsTerminationRequested()) {
+ client_thread->EndWait(client_result);
+ }
+ }
+ }
return result;
}
-Result KServerSession::HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory,
- Core::Timing::CoreTiming& core_timing) {
- return QueueSyncRequest(thread, memory);
+Result KServerSession::ReceiveRequest(std::shared_ptr<HLERequestContext>* out_context,
+ std::weak_ptr<SessionRequestManager> manager) {
+ // Lock the session.
+ KScopedLightLock lk{m_lock};
+
+ // Get the request and client thread.
+ KSessionRequest* request;
+ KThread* client_thread;
+
+ {
+ KScopedSchedulerLock sl{kernel};
+
+ // Ensure that we can service the request.
+ R_UNLESS(!parent->IsClientClosed(), ResultSessionClosed);
+
+ // Ensure we aren't already servicing a request.
+ R_UNLESS(m_current_request == nullptr, ResultNotFound);
+
+ // Ensure we have a request to service.
+ R_UNLESS(!m_request_list.empty(), ResultNotFound);
+
+ // Pop the first request from the list.
+ request = &m_request_list.front();
+ m_request_list.pop_front();
+
+ // Get the thread for the request.
+ client_thread = request->GetThread();
+ R_UNLESS(client_thread != nullptr, ResultSessionClosed);
+
+ // Open the client thread.
+ client_thread->Open();
+ }
+
+ SCOPE_EXIT({ client_thread->Close(); });
+
+ // Set the request as our current.
+ m_current_request = request;
+
+ // Get the client address.
+ uintptr_t client_message = request->GetAddress();
+ size_t client_buffer_size = request->GetSize();
+ // bool recv_list_broken = false;
+
+ // Receive the message.
+ Core::Memory::Memory& memory{kernel.System().Memory()};
+ if (out_context != nullptr) {
+ // HLE request.
+ u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(client_message))};
+ *out_context = std::make_shared<HLERequestContext>(kernel, memory, this, client_thread);
+ (*out_context)->SetSessionRequestManager(manager);
+ (*out_context)
+ ->PopulateFromIncomingCommandBuffer(client_thread->GetOwnerProcess()->GetHandleTable(),
+ cmd_buf);
+ } else {
+ KThread* server_thread{GetCurrentThreadPointer(kernel)};
+ UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess());
+
+ auto* src_msg_buffer = memory.GetPointer(client_message);
+ auto* dst_msg_buffer = memory.GetPointer(server_thread->GetTLSAddress());
+ std::memcpy(dst_msg_buffer, src_msg_buffer, client_buffer_size);
+ }
+
+ // We succeeded.
+ return ResultSuccess;
+}
+
+void KServerSession::CleanupRequests() {
+ KScopedLightLock lk(m_lock);
+
+ // Clean up any pending requests.
+ while (true) {
+ // Get the next request.
+ KSessionRequest* request = nullptr;
+ {
+ KScopedSchedulerLock sl{kernel};
+
+ if (m_current_request) {
+ // Choose the current request if we have one.
+ request = m_current_request;
+ m_current_request = nullptr;
+ } else if (!m_request_list.empty()) {
+ // Pop the request from the front of the list.
+ request = &m_request_list.front();
+ m_request_list.pop_front();
+ }
+ }
+
+ // If there's no request, we're done.
+ if (request == nullptr) {
+ break;
+ }
+
+ // Close a reference to the request once it's cleaned up.
+ SCOPE_EXIT({ request->Close(); });
+
+ // Extract relevant information from the request.
+ // const uintptr_t client_message = request->GetAddress();
+ // const size_t client_buffer_size = request->GetSize();
+ KThread* client_thread = request->GetThread();
+ KEvent* event = request->GetEvent();
+
+ // KProcess *server_process = request->GetServerProcess();
+ // KProcess *client_process = (client_thread != nullptr) ?
+ // client_thread->GetOwnerProcess() : nullptr;
+ // KProcessPageTable *client_page_table = (client_process != nullptr) ?
+ // &client_process->GetPageTable() : nullptr;
+
+ // Cleanup the mappings.
+ // Result result = CleanupMap(request, server_process, client_page_table);
+
+ // If there's a client thread, update it.
+ if (client_thread != nullptr) {
+ if (event != nullptr) {
+ // // We need to reply async.
+ // ReplyAsyncError(client_process, client_message, client_buffer_size,
+ // (R_SUCCEEDED(result) ? ResultSessionClosed : result));
+
+ // // Unlock the client buffer.
+ // NOTE: Nintendo does not check the result of this.
+ // client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size);
+
+ // Signal the event.
+ event->Signal();
+ } else {
+ // End the client thread's wait.
+ KScopedSchedulerLock sl{kernel};
+
+ if (!client_thread->IsTerminationRequested()) {
+ client_thread->EndWait(ResultSessionClosed);
+ }
+ }
+ }
+ }
}
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h
index 6d0821945..6e189af8b 100644
--- a/src/core/hle/kernel/k_server_session.h
+++ b/src/core/hle/kernel/k_server_session.h
@@ -1,8 +1,9 @@
-// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
+#include <list>
#include <memory>
#include <string>
#include <utility>
@@ -10,24 +11,16 @@
#include <boost/intrusive/list.hpp>
#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/kernel/k_light_lock.h"
+#include "core/hle/kernel/k_session_request.h"
#include "core/hle/kernel/k_synchronization_object.h"
#include "core/hle/result.h"
-namespace Core::Memory {
-class Memory;
-}
-
-namespace Core::Timing {
-class CoreTiming;
-struct EventType;
-} // namespace Core::Timing
-
namespace Kernel {
class HLERequestContext;
class KernelCore;
class KSession;
-class SessionRequestHandler;
class SessionRequestManager;
class KThread;
@@ -43,8 +36,7 @@ public:
void Destroy() override;
- void Initialize(KSession* parent_session_, std::string&& name_,
- std::shared_ptr<SessionRequestManager> manager_);
+ void Initialize(KSession* parent_session_, std::string&& name_);
KSession* GetParent() {
return parent;
@@ -55,71 +47,30 @@ public:
}
bool IsSignaled() const override;
-
void OnClientClosed();
- void ClientConnected(SessionRequestHandlerPtr handler) {
- manager->SetSessionHandler(std::move(handler));
- }
-
- void ClientDisconnected() {
- manager = nullptr;
- }
-
- /**
- * Handle a sync request from the emulated application.
- *
- * @param thread Thread that initiated the request.
- * @param memory Memory context to handle the sync request under.
- * @param core_timing Core timing context to schedule the request event under.
- *
- * @returns Result from the operation.
- */
- Result HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory,
- Core::Timing::CoreTiming& core_timing);
-
- /// Adds a new domain request handler to the collection of request handlers within
- /// this ServerSession instance.
- void AppendDomainHandler(SessionRequestHandlerPtr handler);
-
- /// Retrieves the total number of domain request handlers that have been
- /// appended to this ServerSession instance.
- std::size_t NumDomainRequestHandlers() const;
-
- /// Returns true if the session has been converted to a domain, otherwise False
- bool IsDomain() const {
- return manager->IsDomain();
- }
-
- /// Converts the session to a domain at the end of the current command
- void ConvertToDomain() {
- convert_to_domain = true;
- }
+ /// TODO: flesh these out to match the real kernel
+ Result OnRequest(KSessionRequest* request);
+ Result SendReply(bool is_hle = false);
+ Result ReceiveRequest(std::shared_ptr<HLERequestContext>* out_context = nullptr,
+ std::weak_ptr<SessionRequestManager> manager = {});
- /// Gets the session request manager, which forwards requests to the underlying service
- std::shared_ptr<SessionRequestManager>& GetSessionRequestManager() {
- return manager;
+ Result SendReplyHLE() {
+ return SendReply(true);
}
private:
- /// Queues a sync request from the emulated application.
- Result QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory);
-
- /// Completes a sync request from the emulated application.
- Result CompleteSyncRequest(HLERequestContext& context);
-
- /// Handles a SyncRequest to a domain, forwarding the request to the proper object or closing an
- /// object handle.
- Result HandleDomainSyncRequest(Kernel::HLERequestContext& context);
-
- /// This session's HLE request handlers
- std::shared_ptr<SessionRequestManager> manager;
-
- /// When set to True, converts the session to a domain at the end of the command
- bool convert_to_domain{};
+ /// Frees up waiting client sessions when this server session is about to die
+ void CleanupRequests();
/// KSession that owns this KServerSession
KSession* parent{};
+
+ /// List of threads which are pending a reply.
+ boost::intrusive::list<KSessionRequest> m_request_list;
+ KSessionRequest* m_current_request{};
+
+ KLightLock m_lock;
};
} // namespace Kernel
diff --git a/src/core/hle/kernel/k_session.cpp b/src/core/hle/kernel/k_session.cpp
index ee05aa282..7a6534ac3 100644
--- a/src/core/hle/kernel/k_session.cpp
+++ b/src/core/hle/kernel/k_session.cpp
@@ -13,8 +13,7 @@ KSession::KSession(KernelCore& kernel_)
: KAutoObjectWithSlabHeapAndContainer{kernel_}, server{kernel_}, client{kernel_} {}
KSession::~KSession() = default;
-void KSession::Initialize(KClientPort* port_, const std::string& name_,
- std::shared_ptr<SessionRequestManager> manager_) {
+void KSession::Initialize(KClientPort* port_, const std::string& name_) {
// Increment reference count.
// Because reference count is one on creation, this will result
// in a reference count of two. Thus, when both server and client are closed
@@ -26,7 +25,7 @@ void KSession::Initialize(KClientPort* port_, const std::string& name_,
KAutoObject::Create(std::addressof(client));
// Initialize our sub sessions.
- server.Initialize(this, name_ + ":Server", manager_);
+ server.Initialize(this, name_ + ":Server");
client.Initialize(this, name_ + ":Client");
// Set state and name.
diff --git a/src/core/hle/kernel/k_session.h b/src/core/hle/kernel/k_session.h
index c6ead403b..93e5e6f71 100644
--- a/src/core/hle/kernel/k_session.h
+++ b/src/core/hle/kernel/k_session.h
@@ -21,8 +21,7 @@ public:
explicit KSession(KernelCore& kernel_);
~KSession() override;
- void Initialize(KClientPort* port_, const std::string& name_,
- std::shared_ptr<SessionRequestManager> manager_ = nullptr);
+ void Initialize(KClientPort* port_, const std::string& name_);
void Finalize() override;
diff --git a/src/core/hle/kernel/k_session_request.cpp b/src/core/hle/kernel/k_session_request.cpp
new file mode 100644
index 000000000..520da6aa7
--- /dev/null
+++ b/src/core/hle/kernel/k_session_request.cpp
@@ -0,0 +1,61 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/kernel/k_page_buffer.h"
+#include "core/hle/kernel/k_session_request.h"
+
+namespace Kernel {
+
+Result KSessionRequest::SessionMappings::PushMap(VAddr client, VAddr server, size_t size,
+ KMemoryState state, size_t index) {
+ // At most 15 buffers of each type (4-bit descriptor counts).
+ ASSERT(index < ((1ul << 4) - 1) * 3);
+
+ // Get the mapping.
+ Mapping* mapping;
+ if (index < NumStaticMappings) {
+ mapping = &m_static_mappings[index];
+ } else {
+ // Allocate a page for the extra mappings.
+ if (m_mappings == nullptr) {
+ KPageBuffer* page_buffer = KPageBuffer::Allocate(kernel);
+ R_UNLESS(page_buffer != nullptr, ResultOutOfMemory);
+
+ m_mappings = reinterpret_cast<Mapping*>(page_buffer);
+ }
+
+ mapping = &m_mappings[index - NumStaticMappings];
+ }
+
+ // Set the mapping.
+ mapping->Set(client, server, size, state);
+
+ return ResultSuccess;
+}
+
+Result KSessionRequest::SessionMappings::PushSend(VAddr client, VAddr server, size_t size,
+ KMemoryState state) {
+ ASSERT(m_num_recv == 0);
+ ASSERT(m_num_exch == 0);
+ return this->PushMap(client, server, size, state, m_num_send++);
+}
+
+Result KSessionRequest::SessionMappings::PushReceive(VAddr client, VAddr server, size_t size,
+ KMemoryState state) {
+ ASSERT(m_num_exch == 0);
+ return this->PushMap(client, server, size, state, m_num_send + m_num_recv++);
+}
+
+Result KSessionRequest::SessionMappings::PushExchange(VAddr client, VAddr server, size_t size,
+ KMemoryState state) {
+ return this->PushMap(client, server, size, state, m_num_send + m_num_recv + m_num_exch++);
+}
+
+void KSessionRequest::SessionMappings::Finalize() {
+ if (m_mappings) {
+ KPageBuffer::Free(kernel, reinterpret_cast<KPageBuffer*>(m_mappings));
+ m_mappings = nullptr;
+ }
+}
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/k_session_request.h b/src/core/hle/kernel/k_session_request.h
new file mode 100644
index 000000000..e5558bc2c
--- /dev/null
+++ b/src/core/hle/kernel/k_session_request.h
@@ -0,0 +1,306 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+
+#include "core/hle/kernel/k_auto_object.h"
+#include "core/hle/kernel/k_event.h"
+#include "core/hle/kernel/k_memory_block.h"
+#include "core/hle/kernel/k_process.h"
+#include "core/hle/kernel/k_thread.h"
+#include "core/hle/kernel/slab_helpers.h"
+
+namespace Kernel {
+
+class KSessionRequest final : public KSlabAllocated<KSessionRequest>,
+ public KAutoObject,
+ public boost::intrusive::list_base_hook<> {
+ KERNEL_AUTOOBJECT_TRAITS(KSessionRequest, KAutoObject);
+
+public:
+ class SessionMappings {
+ private:
+ static constexpr size_t NumStaticMappings = 8;
+
+ class Mapping {
+ public:
+ constexpr void Set(VAddr c, VAddr s, size_t sz, KMemoryState st) {
+ m_client_address = c;
+ m_server_address = s;
+ m_size = sz;
+ m_state = st;
+ }
+
+ constexpr VAddr GetClientAddress() const {
+ return m_client_address;
+ }
+ constexpr VAddr GetServerAddress() const {
+ return m_server_address;
+ }
+ constexpr size_t GetSize() const {
+ return m_size;
+ }
+ constexpr KMemoryState GetMemoryState() const {
+ return m_state;
+ }
+
+ private:
+ VAddr m_client_address;
+ VAddr m_server_address;
+ size_t m_size;
+ KMemoryState m_state;
+ };
+
+ public:
+ explicit SessionMappings(KernelCore& kernel_) : kernel(kernel_) {}
+
+ void Initialize() {}
+ void Finalize();
+
+ size_t GetSendCount() const {
+ return m_num_send;
+ }
+ size_t GetReceiveCount() const {
+ return m_num_recv;
+ }
+ size_t GetExchangeCount() const {
+ return m_num_exch;
+ }
+
+ Result PushSend(VAddr client, VAddr server, size_t size, KMemoryState state);
+ Result PushReceive(VAddr client, VAddr server, size_t size, KMemoryState state);
+ Result PushExchange(VAddr client, VAddr server, size_t size, KMemoryState state);
+
+ VAddr GetSendClientAddress(size_t i) const {
+ return GetSendMapping(i).GetClientAddress();
+ }
+ VAddr GetSendServerAddress(size_t i) const {
+ return GetSendMapping(i).GetServerAddress();
+ }
+ size_t GetSendSize(size_t i) const {
+ return GetSendMapping(i).GetSize();
+ }
+ KMemoryState GetSendMemoryState(size_t i) const {
+ return GetSendMapping(i).GetMemoryState();
+ }
+
+ VAddr GetReceiveClientAddress(size_t i) const {
+ return GetReceiveMapping(i).GetClientAddress();
+ }
+ VAddr GetReceiveServerAddress(size_t i) const {
+ return GetReceiveMapping(i).GetServerAddress();
+ }
+ size_t GetReceiveSize(size_t i) const {
+ return GetReceiveMapping(i).GetSize();
+ }
+ KMemoryState GetReceiveMemoryState(size_t i) const {
+ return GetReceiveMapping(i).GetMemoryState();
+ }
+
+ VAddr GetExchangeClientAddress(size_t i) const {
+ return GetExchangeMapping(i).GetClientAddress();
+ }
+ VAddr GetExchangeServerAddress(size_t i) const {
+ return GetExchangeMapping(i).GetServerAddress();
+ }
+ size_t GetExchangeSize(size_t i) const {
+ return GetExchangeMapping(i).GetSize();
+ }
+ KMemoryState GetExchangeMemoryState(size_t i) const {
+ return GetExchangeMapping(i).GetMemoryState();
+ }
+
+ private:
+ Result PushMap(VAddr client, VAddr server, size_t size, KMemoryState state, size_t index);
+
+ const Mapping& GetSendMapping(size_t i) const {
+ ASSERT(i < m_num_send);
+
+ const size_t index = i;
+ if (index < NumStaticMappings) {
+ return m_static_mappings[index];
+ } else {
+ return m_mappings[index - NumStaticMappings];
+ }
+ }
+
+ const Mapping& GetReceiveMapping(size_t i) const {
+ ASSERT(i < m_num_recv);
+
+ const size_t index = m_num_send + i;
+ if (index < NumStaticMappings) {
+ return m_static_mappings[index];
+ } else {
+ return m_mappings[index - NumStaticMappings];
+ }
+ }
+
+ const Mapping& GetExchangeMapping(size_t i) const {
+ ASSERT(i < m_num_exch);
+
+ const size_t index = m_num_send + m_num_recv + i;
+ if (index < NumStaticMappings) {
+ return m_static_mappings[index];
+ } else {
+ return m_mappings[index - NumStaticMappings];
+ }
+ }
+
+ private:
+ KernelCore& kernel;
+ std::array<Mapping, NumStaticMappings> m_static_mappings;
+ Mapping* m_mappings{};
+ u8 m_num_send{};
+ u8 m_num_recv{};
+ u8 m_num_exch{};
+ };
+
+public:
+ explicit KSessionRequest(KernelCore& kernel_) : KAutoObject(kernel_), m_mappings(kernel_) {}
+
+ static KSessionRequest* Create(KernelCore& kernel) {
+ KSessionRequest* req = KSessionRequest::Allocate(kernel);
+ if (req != nullptr) [[likely]] {
+ KAutoObject::Create(req);
+ }
+ return req;
+ }
+
+ void Destroy() override {
+ this->Finalize();
+ KSessionRequest::Free(kernel, this);
+ }
+
+ void Initialize(KEvent* event, uintptr_t address, size_t size) {
+ m_mappings.Initialize();
+
+ m_thread = GetCurrentThreadPointer(kernel);
+ m_event = event;
+ m_address = address;
+ m_size = size;
+
+ m_thread->Open();
+ if (m_event != nullptr) {
+ m_event->Open();
+ }
+ }
+
+ static void PostDestroy(uintptr_t arg) {}
+
+ KThread* GetThread() const {
+ return m_thread;
+ }
+ KEvent* GetEvent() const {
+ return m_event;
+ }
+ uintptr_t GetAddress() const {
+ return m_address;
+ }
+ size_t GetSize() const {
+ return m_size;
+ }
+ KProcess* GetServerProcess() const {
+ return m_server;
+ }
+
+ void SetServerProcess(KProcess* process) {
+ m_server = process;
+ m_server->Open();
+ }
+
+ void ClearThread() {
+ m_thread = nullptr;
+ }
+ void ClearEvent() {
+ m_event = nullptr;
+ }
+
+ size_t GetSendCount() const {
+ return m_mappings.GetSendCount();
+ }
+ size_t GetReceiveCount() const {
+ return m_mappings.GetReceiveCount();
+ }
+ size_t GetExchangeCount() const {
+ return m_mappings.GetExchangeCount();
+ }
+
+ Result PushSend(VAddr client, VAddr server, size_t size, KMemoryState state) {
+ return m_mappings.PushSend(client, server, size, state);
+ }
+
+ Result PushReceive(VAddr client, VAddr server, size_t size, KMemoryState state) {
+ return m_mappings.PushReceive(client, server, size, state);
+ }
+
+ Result PushExchange(VAddr client, VAddr server, size_t size, KMemoryState state) {
+ return m_mappings.PushExchange(client, server, size, state);
+ }
+
+ VAddr GetSendClientAddress(size_t i) const {
+ return m_mappings.GetSendClientAddress(i);
+ }
+ VAddr GetSendServerAddress(size_t i) const {
+ return m_mappings.GetSendServerAddress(i);
+ }
+ size_t GetSendSize(size_t i) const {
+ return m_mappings.GetSendSize(i);
+ }
+ KMemoryState GetSendMemoryState(size_t i) const {
+ return m_mappings.GetSendMemoryState(i);
+ }
+
+ VAddr GetReceiveClientAddress(size_t i) const {
+ return m_mappings.GetReceiveClientAddress(i);
+ }
+ VAddr GetReceiveServerAddress(size_t i) const {
+ return m_mappings.GetReceiveServerAddress(i);
+ }
+ size_t GetReceiveSize(size_t i) const {
+ return m_mappings.GetReceiveSize(i);
+ }
+ KMemoryState GetReceiveMemoryState(size_t i) const {
+ return m_mappings.GetReceiveMemoryState(i);
+ }
+
+ VAddr GetExchangeClientAddress(size_t i) const {
+ return m_mappings.GetExchangeClientAddress(i);
+ }
+ VAddr GetExchangeServerAddress(size_t i) const {
+ return m_mappings.GetExchangeServerAddress(i);
+ }
+ size_t GetExchangeSize(size_t i) const {
+ return m_mappings.GetExchangeSize(i);
+ }
+ KMemoryState GetExchangeMemoryState(size_t i) const {
+ return m_mappings.GetExchangeMemoryState(i);
+ }
+
+private:
+ // NOTE: This is public and virtual in Nintendo's kernel.
+ void Finalize() override {
+ m_mappings.Finalize();
+
+ if (m_thread) {
+ m_thread->Close();
+ }
+ if (m_event) {
+ m_event->Close();
+ }
+ if (m_server) {
+ m_server->Close();
+ }
+ }
+
+private:
+ SessionMappings m_mappings;
+ KThread* m_thread{};
+ KProcess* m_server{};
+ KEvent* m_event{};
+ uintptr_t m_address{};
+ size_t m_size{};
+};
+
+} // namespace Kernel
diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp
index 8ff1545b6..a039cc591 100644
--- a/src/core/hle/kernel/k_shared_memory.cpp
+++ b/src/core/hle/kernel/k_shared_memory.cpp
@@ -50,7 +50,7 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory_, KProcess* o
is_initialized = true;
// Clear all pages in the memory.
- std::memset(device_memory_.GetPointer(physical_address_), 0, size_);
+ std::memset(device_memory_.GetPointer<void>(physical_address_), 0, size_);
return ResultSuccess;
}
diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h
index 34cb98456..5620c3660 100644
--- a/src/core/hle/kernel/k_shared_memory.h
+++ b/src/core/hle/kernel/k_shared_memory.h
@@ -54,7 +54,7 @@ public:
* @return A pointer to the shared memory block from the specified offset
*/
u8* GetPointer(std::size_t offset = 0) {
- return device_memory->GetPointer(physical_address + offset);
+ return device_memory->GetPointer<u8>(physical_address + offset);
}
/**
@@ -63,7 +63,7 @@ public:
* @return A pointer to the shared memory block from the specified offset
*/
const u8* GetPointer(std::size_t offset = 0) const {
- return device_memory->GetPointer(physical_address + offset);
+ return device_memory->GetPointer<u8>(physical_address + offset);
}
void Finalize() override;
diff --git a/src/core/hle/kernel/k_shared_memory_info.h b/src/core/hle/kernel/k_shared_memory_info.h
index e43db8515..2bb6b6d08 100644
--- a/src/core/hle/kernel/k_shared_memory_info.h
+++ b/src/core/hle/kernel/k_shared_memory_info.h
@@ -15,7 +15,8 @@ class KSharedMemoryInfo final : public KSlabAllocated<KSharedMemoryInfo>,
public boost::intrusive::list_base_hook<> {
public:
- explicit KSharedMemoryInfo() = default;
+ explicit KSharedMemoryInfo(KernelCore&) {}
+ KSharedMemoryInfo() = default;
constexpr void Initialize(KSharedMemory* shmem) {
shared_memory = shmem;
diff --git a/src/core/hle/kernel/k_slab_heap.h b/src/core/hle/kernel/k_slab_heap.h
index 2b303537e..a8c77a7d4 100644
--- a/src/core/hle/kernel/k_slab_heap.h
+++ b/src/core/hle/kernel/k_slab_heap.h
@@ -8,6 +8,7 @@
#include "common/assert.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
+#include "common/spin_lock.h"
namespace Kernel {
@@ -36,28 +37,34 @@ public:
}
void* Allocate() {
- Node* ret = m_head.load();
+ // KScopedInterruptDisable di;
- do {
- if (ret == nullptr) {
- break;
- }
- } while (!m_head.compare_exchange_weak(ret, ret->next));
+ m_lock.lock();
+
+ Node* ret = m_head;
+ if (ret != nullptr) [[likely]] {
+ m_head = ret->next;
+ }
+ m_lock.unlock();
return ret;
}
void Free(void* obj) {
+ // KScopedInterruptDisable di;
+
+ m_lock.lock();
+
Node* node = static_cast<Node*>(obj);
+ node->next = m_head;
+ m_head = node;
- Node* cur_head = m_head.load();
- do {
- node->next = cur_head;
- } while (!m_head.compare_exchange_weak(cur_head, node));
+ m_lock.unlock();
}
private:
std::atomic<Node*> m_head{};
+ Common::SpinLock m_lock;
};
} // namespace impl
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 174afc80d..cc88d08f0 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -30,6 +30,7 @@
#include "core/hle/kernel/k_worker_task_manager.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc_results.h"
+#include "core/hle/kernel/svc_types.h"
#include "core/hle/result.h"
#include "core/memory.h"
@@ -38,6 +39,9 @@
#endif
namespace {
+
+constexpr inline s32 TerminatingThreadPriority = Kernel::Svc::SystemThreadPriorityHighest - 1;
+
static void ResetThreadContext32(Core::ARM_Interface::ThreadContext32& context, u32 stack_top,
u32 entry_point, u32 arg) {
context = {};
@@ -144,7 +148,9 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack
physical_affinity_mask.SetAffinity(phys_core, true);
// Set the thread state.
- thread_state = (type == ThreadType::Main) ? ThreadState::Runnable : ThreadState::Initialized;
+ thread_state = (type == ThreadType::Main || type == ThreadType::Dummy)
+ ? ThreadState::Runnable
+ : ThreadState::Initialized;
// Set TLS address.
tls_address = 0;
@@ -241,7 +247,7 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack
}
}
- return ResultSuccess;
+ R_SUCCEED();
}
Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg,
@@ -254,7 +260,7 @@ Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_
thread->host_context = std::make_shared<Common::Fiber>(std::move(init_func));
thread->is_single_core = !Settings::values.use_multi_core.GetValue();
- return ResultSuccess;
+ R_SUCCEED();
}
Result KThread::InitializeDummyThread(KThread* thread) {
@@ -264,31 +270,32 @@ Result KThread::InitializeDummyThread(KThread* thread) {
// Initialize emulation parameters.
thread->stack_parameters.disable_count = 0;
- return ResultSuccess;
+ R_SUCCEED();
}
Result KThread::InitializeMainThread(Core::System& system, KThread* thread, s32 virt_core) {
- return InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main,
- system.GetCpuManager().GetGuestActivateFunc());
+ R_RETURN(InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {},
+ ThreadType::Main, system.GetCpuManager().GetGuestActivateFunc()));
}
Result KThread::InitializeIdleThread(Core::System& system, KThread* thread, s32 virt_core) {
- return InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main,
- system.GetCpuManager().GetIdleThreadStartFunc());
+ R_RETURN(InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {},
+ ThreadType::Main, system.GetCpuManager().GetIdleThreadStartFunc()));
}
Result KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread,
KThreadFunction func, uintptr_t arg, s32 virt_core) {
- return InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr, ThreadType::HighPriority,
- system.GetCpuManager().GetShutdownThreadStartFunc());
+ R_RETURN(InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr,
+ ThreadType::HighPriority,
+ system.GetCpuManager().GetShutdownThreadStartFunc()));
}
Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func,
uintptr_t arg, VAddr user_stack_top, s32 prio, s32 virt_core,
KProcess* owner) {
system.Kernel().GlobalSchedulerContext().AddThread(thread);
- return InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner,
- ThreadType::User, system.GetCpuManager().GetGuestThreadFunc());
+ R_RETURN(InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner,
+ ThreadType::User, system.GetCpuManager().GetGuestThreadFunc()));
}
void KThread::PostDestroy(uintptr_t arg) {
@@ -538,7 +545,7 @@ Result KThread::GetCoreMask(s32* out_ideal_core, u64* out_affinity_mask) {
*out_ideal_core = virtual_ideal_core_id;
*out_affinity_mask = virtual_affinity_mask;
- return ResultSuccess;
+ R_SUCCEED();
}
Result KThread::GetPhysicalCoreMask(s32* out_ideal_core, u64* out_affinity_mask) {
@@ -554,7 +561,7 @@ Result KThread::GetPhysicalCoreMask(s32* out_ideal_core, u64* out_affinity_mask)
*out_affinity_mask = original_physical_affinity_mask.GetAffinityMask();
}
- return ResultSuccess;
+ R_SUCCEED();
}
Result KThread::SetCoreMask(s32 core_id_, u64 v_affinity_mask) {
@@ -666,7 +673,7 @@ Result KThread::SetCoreMask(s32 core_id_, u64 v_affinity_mask) {
} while (retry_update);
}
- return ResultSuccess;
+ R_SUCCEED();
}
void KThread::SetBasePriority(s32 value) {
@@ -839,7 +846,7 @@ Result KThread::SetActivity(Svc::ThreadActivity activity) {
} while (thread_is_current);
}
- return ResultSuccess;
+ R_SUCCEED();
}
Result KThread::GetThreadContext3(std::vector<u8>& out) {
@@ -874,7 +881,7 @@ Result KThread::GetThreadContext3(std::vector<u8>& out) {
}
}
- return ResultSuccess;
+ R_SUCCEED();
}
void KThread::AddWaiterImpl(KThread* thread) {
@@ -1038,7 +1045,7 @@ Result KThread::Run() {
// Set our state and finish.
SetState(ThreadState::Runnable);
- return ResultSuccess;
+ R_SUCCEED();
}
}
@@ -1073,6 +1080,78 @@ void KThread::Exit() {
UNREACHABLE_MSG("KThread::Exit() would return");
}
+Result KThread::Terminate() {
+ ASSERT(this != GetCurrentThreadPointer(kernel));
+
+ // Request the thread terminate if it hasn't already.
+ if (const auto new_state = this->RequestTerminate(); new_state != ThreadState::Terminated) {
+ // If the thread isn't terminated, wait for it to terminate.
+ s32 index;
+ KSynchronizationObject* objects[] = {this};
+ R_TRY(KSynchronizationObject::Wait(kernel, std::addressof(index), objects, 1,
+ Svc::WaitInfinite));
+ }
+
+ R_SUCCEED();
+}
+
+ThreadState KThread::RequestTerminate() {
+ ASSERT(this != GetCurrentThreadPointer(kernel));
+
+ KScopedSchedulerLock sl{kernel};
+
+ // Determine if this is the first termination request.
+ const bool first_request = [&]() -> bool {
+ // Perform an atomic compare-and-swap from false to true.
+ bool expected = false;
+ return termination_requested.compare_exchange_strong(expected, true);
+ }();
+
+ // If this is the first request, start termination procedure.
+ if (first_request) {
+ // If the thread is in initialized state, just change state to terminated.
+ if (this->GetState() == ThreadState::Initialized) {
+ thread_state = ThreadState::Terminated;
+ return ThreadState::Terminated;
+ }
+
+ // Register the terminating dpc.
+ this->RegisterDpc(DpcFlag::Terminating);
+
+ // If the thread is pinned, unpin it.
+ if (this->GetStackParameters().is_pinned) {
+ this->GetOwnerProcess()->UnpinThread(this);
+ }
+
+ // If the thread is suspended, continue it.
+ if (this->IsSuspended()) {
+ suspend_allowed_flags = 0;
+ this->UpdateState();
+ }
+
+ // Change the thread's priority to be higher than any system thread's.
+ if (this->GetBasePriority() >= Svc::SystemThreadPriorityHighest) {
+ this->SetBasePriority(TerminatingThreadPriority);
+ }
+
+ // If the thread is runnable, send a termination interrupt to other cores.
+ if (this->GetState() == ThreadState::Runnable) {
+ if (const u64 core_mask =
+ physical_affinity_mask.GetAffinityMask() & ~(1ULL << GetCurrentCoreId(kernel));
+ core_mask != 0) {
+ Kernel::KInterruptManager::SendInterProcessorInterrupt(kernel, core_mask);
+ }
+ }
+
+ // Wake up the thread.
+ if (this->GetState() == ThreadState::Waiting) {
+ wait_queue->CancelWait(this, ResultTerminationRequested, true);
+ }
+ }
+
+ return this->GetState();
+}
+
Result KThread::Sleep(s64 timeout) {
ASSERT(!kernel.GlobalSchedulerContext().IsLocked());
ASSERT(this == GetCurrentThreadPointer(kernel));
@@ -1086,7 +1165,7 @@ Result KThread::Sleep(s64 timeout) {
// Check if the thread should terminate.
if (this->IsTerminationRequested()) {
slp.CancelSleep();
- return ResultTerminationRequested;
+ R_THROW(ResultTerminationRequested);
}
// Wait for the sleep to end.
@@ -1094,33 +1173,34 @@ Result KThread::Sleep(s64 timeout) {
SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Sleep);
}
- return ResultSuccess;
+ R_SUCCEED();
}
-void KThread::IfDummyThreadTryWait() {
- if (!IsDummyThread()) {
- return;
- }
+void KThread::RequestDummyThreadWait() {
+ ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
+ ASSERT(this->IsDummyThread());
+
+ // We will block when the scheduler lock is released.
+ dummy_thread_runnable.store(false);
+}
- if (GetState() != ThreadState::Waiting) {
+void KThread::DummyThreadBeginWait() {
+ if (!this->IsDummyThread() || kernel.IsPhantomModeForSingleCore()) {
+ // Occurs in single core mode.
return;
}
- ASSERT(!kernel.IsPhantomModeForSingleCore());
-
- // Block until we are no longer waiting.
- std::unique_lock lk(dummy_wait_lock);
- dummy_wait_cv.wait(
- lk, [&] { return GetState() != ThreadState::Waiting || kernel.IsShuttingDown(); });
+ // Block until runnable is no longer false.
+ dummy_thread_runnable.wait(false);
}
-void KThread::IfDummyThreadEndWait() {
- if (!IsDummyThread()) {
- return;
- }
+void KThread::DummyThreadEndWait() {
+ ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
+ ASSERT(this->IsDummyThread());
// Wake up the waiting thread.
- dummy_wait_cv.notify_one();
+ dummy_thread_runnable.store(true);
+ dummy_thread_runnable.notify_one();
}
void KThread::BeginWait(KThreadQueue* queue) {
@@ -1154,9 +1234,6 @@ void KThread::EndWait(Result wait_result_) {
}
wait_queue->EndWait(this, wait_result_);
-
- // Special case for dummy threads to wakeup if necessary.
- IfDummyThreadEndWait();
}
}
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index 9ee20208e..30aa10c9a 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -180,6 +180,10 @@ public:
void Exit();
+ Result Terminate();
+
+ ThreadState RequestTerminate();
+
[[nodiscard]] u32 GetSuspendFlags() const {
return suspend_allowed_flags & suspend_request_flags;
}
@@ -639,8 +643,9 @@ public:
// therefore will not block on guest kernel synchronization primitives. These methods handle
// blocking as needed.
- void IfDummyThreadTryWait();
- void IfDummyThreadEndWait();
+ void RequestDummyThreadWait();
+ void DummyThreadBeginWait();
+ void DummyThreadEndWait();
[[nodiscard]] uintptr_t GetArgument() const {
return argument;
@@ -773,8 +778,7 @@ private:
bool is_single_core{};
ThreadType thread_type{};
StepState step_state{};
- std::mutex dummy_wait_lock;
- std::condition_variable dummy_wait_cv;
+ std::atomic<bool> dummy_thread_runnable{true};
// For debugging
std::vector<KSynchronizationObject*> wait_objects_for_debugging;
diff --git a/src/core/hle/kernel/k_thread_local_page.h b/src/core/hle/kernel/k_thread_local_page.h
index 0a7f22680..5d466ace7 100644
--- a/src/core/hle/kernel/k_thread_local_page.h
+++ b/src/core/hle/kernel/k_thread_local_page.h
@@ -26,7 +26,7 @@ public:
static_assert(RegionsPerPage > 0);
public:
- constexpr explicit KThreadLocalPage(VAddr addr = {}) : m_virt_addr(addr) {
+ constexpr explicit KThreadLocalPage(KernelCore&, VAddr addr = {}) : m_virt_addr(addr) {
m_is_region_free.fill(true);
}
diff --git a/src/core/hle/kernel/k_worker_task_manager.cpp b/src/core/hle/kernel/k_worker_task_manager.cpp
index 221f341ee..04042bf8f 100644
--- a/src/core/hle/kernel/k_worker_task_manager.cpp
+++ b/src/core/hle/kernel/k_worker_task_manager.cpp
@@ -23,7 +23,7 @@ void KWorkerTask::DoWorkerTask() {
}
}
-KWorkerTaskManager::KWorkerTaskManager() : m_waiting_thread(1, "yuzu:KWorkerTaskManager") {}
+KWorkerTaskManager::KWorkerTaskManager() : m_waiting_thread(1, "KWorkerTaskManager") {}
void KWorkerTaskManager::AddTask(KernelCore& kernel, WorkerType type, KWorkerTask* task) {
ASSERT(type <= WorkerType::Count);
diff --git a/src/core/hle/kernel/k_writable_event.cpp b/src/core/hle/kernel/k_writable_event.cpp
deleted file mode 100644
index ff88c5acd..000000000
--- a/src/core/hle/kernel/k_writable_event.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/hle/kernel/k_event.h"
-#include "core/hle/kernel/k_readable_event.h"
-#include "core/hle/kernel/k_writable_event.h"
-
-namespace Kernel {
-
-KWritableEvent::KWritableEvent(KernelCore& kernel_)
- : KAutoObjectWithSlabHeapAndContainer{kernel_} {}
-
-KWritableEvent::~KWritableEvent() = default;
-
-void KWritableEvent::Initialize(KEvent* parent_event_, std::string&& name_) {
- parent = parent_event_;
- name = std::move(name_);
- parent->GetReadableEvent().Open();
-}
-
-Result KWritableEvent::Signal() {
- return parent->GetReadableEvent().Signal();
-}
-
-Result KWritableEvent::Clear() {
- return parent->GetReadableEvent().Clear();
-}
-
-void KWritableEvent::Destroy() {
- // Close our references.
- parent->GetReadableEvent().Close();
- parent->Close();
-}
-
-} // namespace Kernel
diff --git a/src/core/hle/kernel/k_writable_event.h b/src/core/hle/kernel/k_writable_event.h
deleted file mode 100644
index 3fd0c7d0a..000000000
--- a/src/core/hle/kernel/k_writable_event.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/kernel/k_auto_object.h"
-#include "core/hle/kernel/slab_helpers.h"
-#include "core/hle/result.h"
-
-namespace Kernel {
-
-class KernelCore;
-class KEvent;
-
-class KWritableEvent final
- : public KAutoObjectWithSlabHeapAndContainer<KWritableEvent, KAutoObjectWithList> {
- KERNEL_AUTOOBJECT_TRAITS(KWritableEvent, KAutoObject);
-
-public:
- explicit KWritableEvent(KernelCore& kernel_);
- ~KWritableEvent() override;
-
- void Destroy() override;
-
- static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
-
- void Initialize(KEvent* parent_, std::string&& name_);
- Result Signal();
- Result Clear();
-
- KEvent* GetParent() const {
- return parent;
- }
-
-private:
- KEvent* parent{};
-};
-
-} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index ce7fa8275..09c36ee09 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -24,6 +24,7 @@
#include "core/hardware_properties.h"
#include "core/hle/kernel/init/init_slab_setup.h"
#include "core/hle/kernel/k_client_port.h"
+#include "core/hle/kernel/k_dynamic_resource_manager.h"
#include "core/hle/kernel/k_handle_table.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_memory_manager.h"
@@ -47,8 +48,8 @@ namespace Kernel {
struct KernelCore::Impl {
explicit Impl(Core::System& system_, KernelCore& kernel_)
- : time_manager{system_},
- service_threads_manager{1, "yuzu:ServiceThreadsManager"}, system{system_} {}
+ : time_manager{system_}, service_threads_manager{1, "ServiceThreadsManager"},
+ service_thread_barrier{2}, system{system_} {}
void SetMulticore(bool is_multi) {
is_multicore = is_multi;
@@ -59,7 +60,6 @@ struct KernelCore::Impl {
global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel);
global_handle_table->Initialize(KHandleTable::MaxTableSize);
- default_service_thread = CreateServiceThread(kernel, "DefaultServiceThread");
is_phantom_mode_for_singlecore = false;
@@ -73,10 +73,20 @@ struct KernelCore::Impl {
InitializeMemoryLayout();
Init::InitializeKPageBufferSlabHeap(system);
InitializeShutdownThreads();
- InitializePreemption(kernel);
InitializePhysicalCores();
+ InitializePreemption(kernel);
+
+ // Initialize the Dynamic Slab Heaps.
+ {
+ const auto& pt_heap_region = memory_layout->GetPageTableHeapRegion();
+ ASSERT(pt_heap_region.GetEndAddress() != 0);
+
+ InitializeResourceManagers(pt_heap_region.GetAddress(), pt_heap_region.GetSize());
+ }
RegisterHostThread();
+
+ default_service_thread = CreateServiceThread(kernel, "DefaultServiceThread");
}
void InitializeCores() {
@@ -86,6 +96,15 @@ struct KernelCore::Impl {
}
}
+ void CloseCurrentProcess() {
+ (*current_process).Finalize();
+ // current_process->Close();
+ // TODO: The current process should be destroyed based on accurate ref counting after
+ // calling Close(). Adding a manual Destroy() call instead to avoid a memory leak.
+ (*current_process).Destroy();
+ current_process = nullptr;
+ }
+
void Shutdown() {
is_shutting_down.store(true, std::memory_order_relaxed);
SCOPE_EXIT({ is_shutting_down.store(false, std::memory_order_relaxed); });
@@ -99,10 +118,6 @@ struct KernelCore::Impl {
next_user_process_id = KProcess::ProcessIDMin;
next_thread_id = 1;
- for (auto& core : cores) {
- core = nullptr;
- }
-
global_handle_table->Finalize();
global_handle_table.reset();
@@ -152,15 +167,7 @@ struct KernelCore::Impl {
}
}
- // Shutdown all processes.
- if (current_process) {
- (*current_process).Finalize();
- // current_process->Close();
- // TODO: The current process should be destroyed based on accurate ref counting after
- // calling Close(). Adding a manual Destroy() call instead to avoid a memory leak.
- (*current_process).Destroy();
- current_process = nullptr;
- }
+ CloseCurrentProcess();
// Track kernel objects that were not freed on shutdown
{
@@ -178,17 +185,6 @@ struct KernelCore::Impl {
}
void CloseServices() {
- // Close all open server sessions and ports.
- std::unordered_set<KAutoObject*> server_objects_;
- {
- std::scoped_lock lk(server_objects_lock);
- server_objects_ = server_objects;
- server_objects.clear();
- }
- for (auto* server_object : server_objects_) {
- server_object->Close();
- }
-
// Ensures all service threads gracefully shutdown.
ClearServiceThreads();
}
@@ -257,6 +253,18 @@ struct KernelCore::Impl {
system.CoreTiming().ScheduleLoopingEvent(time_interval, time_interval, preemption_event);
}
+ void InitializeResourceManagers(VAddr address, size_t size) {
+ dynamic_page_manager = std::make_unique<KDynamicPageManager>();
+ memory_block_heap = std::make_unique<KMemoryBlockSlabHeap>();
+ app_memory_block_manager = std::make_unique<KMemoryBlockSlabManager>();
+
+ dynamic_page_manager->Initialize(address, size);
+ static constexpr size_t ApplicationMemoryBlockSlabHeapSize = 20000;
+ memory_block_heap->Initialize(dynamic_page_manager.get(),
+ ApplicationMemoryBlockSlabHeapSize);
+ app_memory_block_manager->Initialize(nullptr, memory_block_heap.get());
+ }
+
void InitializeShutdownThreads() {
for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) {
shutdown_threads[core_id] = KThread::Create(system.Kernel());
@@ -328,6 +336,8 @@ struct KernelCore::Impl {
return this_id;
}
+ static inline thread_local bool is_phantom_mode_for_singlecore{false};
+
bool IsPhantomModeForSingleCore() const {
return is_phantom_mode_for_singlecore;
}
@@ -344,11 +354,6 @@ struct KernelCore::Impl {
static inline thread_local KThread* current_thread{nullptr};
KThread* GetCurrentEmuThread() {
- // If we are shutting down the kernel, none of this is relevant anymore.
- if (IsShuttingDown()) {
- return {};
- }
-
const auto thread_id = GetCurrentHostThreadID();
if (thread_id >= Core::Hardware::NUM_CPU_CORES) {
return GetHostDummyThread();
@@ -685,24 +690,21 @@ struct KernelCore::Impl {
return {};
}
- KClientPort* port = &search->second(system.ServiceManager(), system);
- RegisterServerObject(&port->GetParent()->GetServerPort());
- return port;
+ return &search->second(system.ServiceManager(), system);
}
- void RegisterServerObject(KAutoObject* server_object) {
- std::scoped_lock lk(server_objects_lock);
- server_objects.insert(server_object);
- }
+ void RegisterNamedServiceHandler(std::string name, KServerPort* server_port) {
+ auto search = service_interface_handlers.find(name);
+ if (search == service_interface_handlers.end()) {
+ return;
+ }
- void UnregisterServerObject(KAutoObject* server_object) {
- std::scoped_lock lk(server_objects_lock);
- server_objects.erase(server_object);
+ search->second(system.ServiceManager(), server_port);
}
std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(KernelCore& kernel,
const std::string& name) {
- auto service_thread = std::make_shared<Kernel::ServiceThread>(kernel, 1, name);
+ auto service_thread = std::make_shared<Kernel::ServiceThread>(kernel, name);
service_threads_manager.QueueWork(
[this, service_thread]() { service_threads.emplace(service_thread); });
@@ -724,10 +726,14 @@ struct KernelCore::Impl {
}
void ClearServiceThreads() {
- service_threads_manager.QueueWork([this]() { service_threads.clear(); });
+ service_threads_manager.QueueWork([this] {
+ service_threads.clear();
+ default_service_thread.reset();
+ service_thread_barrier.Sync();
+ });
+ service_thread_barrier.Sync();
}
- std::mutex server_objects_lock;
std::mutex registered_objects_lock;
std::mutex registered_in_use_objects_lock;
@@ -756,8 +762,8 @@ struct KernelCore::Impl {
/// Map of named ports managed by the kernel, which can be retrieved using
/// the ConnectToPort SVC.
std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory;
+ std::unordered_map<std::string, ServiceInterfaceHandlerFn> service_interface_handlers;
NamedPortTable named_ports;
- std::unordered_set<KAutoObject*> server_objects;
std::unordered_set<KAutoObject*> registered_objects;
std::unordered_set<KAutoObject*> registered_in_use_objects;
@@ -770,6 +776,11 @@ struct KernelCore::Impl {
// Kernel memory management
std::unique_ptr<KMemoryManager> memory_manager;
+ // Dynamic slab managers
+ std::unique_ptr<KDynamicPageManager> dynamic_page_manager;
+ std::unique_ptr<KMemoryBlockSlabHeap> memory_block_heap;
+ std::unique_ptr<KMemoryBlockSlabManager> app_memory_block_manager;
+
// Shared memory for services
Kernel::KSharedMemory* hid_shared_mem{};
Kernel::KSharedMemory* font_shared_mem{};
@@ -784,13 +795,13 @@ struct KernelCore::Impl {
std::unordered_set<std::shared_ptr<ServiceThread>> service_threads;
std::weak_ptr<ServiceThread> default_service_thread;
Common::ThreadWorker service_threads_manager;
+ Common::Barrier service_thread_barrier;
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads;
std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{};
bool is_multicore{};
std::atomic_bool is_shutting_down{};
- bool is_phantom_mode_for_singlecore{};
u32 single_core_thread_id{};
std::array<u64, Core::Hardware::NUM_CPU_CORES> svc_ticks{};
@@ -853,6 +864,10 @@ const KProcess* KernelCore::CurrentProcess() const {
return impl->current_process;
}
+void KernelCore::CloseCurrentProcess() {
+ impl->CloseCurrentProcess();
+}
+
const std::vector<KProcess*>& KernelCore::GetProcessList() const {
return impl->process_list;
}
@@ -953,16 +968,17 @@ void KernelCore::RegisterNamedService(std::string name, ServiceInterfaceFactory&
impl->service_interface_factory.emplace(std::move(name), factory);
}
-KClientPort* KernelCore::CreateNamedServicePort(std::string name) {
- return impl->CreateNamedServicePort(std::move(name));
+void KernelCore::RegisterInterfaceForNamedService(std::string name,
+ ServiceInterfaceHandlerFn&& handler) {
+ impl->service_interface_handlers.emplace(std::move(name), handler);
}
-void KernelCore::RegisterServerObject(KAutoObject* server_object) {
- impl->RegisterServerObject(server_object);
+KClientPort* KernelCore::CreateNamedServicePort(std::string name) {
+ return impl->CreateNamedServicePort(std::move(name));
}
-void KernelCore::UnregisterServerObject(KAutoObject* server_object) {
- impl->UnregisterServerObject(server_object);
+void KernelCore::RegisterNamedServiceHandler(std::string name, KServerPort* server_port) {
+ impl->RegisterNamedServiceHandler(std::move(name), server_port);
}
void KernelCore::RegisterKernelObject(KAutoObject* object) {
@@ -1041,6 +1057,14 @@ const KMemoryManager& KernelCore::MemoryManager() const {
return *impl->memory_manager;
}
+KMemoryBlockSlabManager& KernelCore::GetApplicationMemoryBlockManager() {
+ return *impl->app_memory_block_manager;
+}
+
+const KMemoryBlockSlabManager& KernelCore::GetApplicationMemoryBlockManager() const {
+ return *impl->app_memory_block_manager;
+}
+
Kernel::KSharedMemory& KernelCore::GetHidSharedMem() {
return *impl->hid_shared_mem;
}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index bcf016a97..4ae6b3923 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -37,6 +37,7 @@ class KClientSession;
class KEvent;
class KHandleTable;
class KLinkedListNode;
+class KMemoryBlockSlabManager;
class KMemoryLayout;
class KMemoryManager;
class KPageBuffer;
@@ -44,15 +45,16 @@ class KPort;
class KProcess;
class KResourceLimit;
class KScheduler;
+class KServerPort;
class KServerSession;
class KSession;
+class KSessionRequest;
class KSharedMemory;
class KSharedMemoryInfo;
class KThread;
class KThreadLocalPage;
class KTransferMemory;
class KWorkerTaskManager;
-class KWritableEvent;
class KCodeMemory;
class PhysicalCore;
class ServiceThread;
@@ -62,6 +64,8 @@ class TimeManager;
using ServiceInterfaceFactory =
std::function<KClientPort&(Service::SM::ServiceManager&, Core::System&)>;
+using ServiceInterfaceHandlerFn = std::function<void(Service::SM::ServiceManager&, KServerPort*)>;
+
namespace Init {
struct KSlabResourceCounts;
}
@@ -131,6 +135,9 @@ public:
/// Retrieves a const pointer to the current process.
const KProcess* CurrentProcess() const;
+ /// Closes the current process.
+ void CloseCurrentProcess();
+
/// Retrieves the list of processes.
const std::vector<KProcess*>& GetProcessList() const;
@@ -188,16 +195,14 @@ public:
/// Registers a named HLE service, passing a factory used to open a port to that service.
void RegisterNamedService(std::string name, ServiceInterfaceFactory&& factory);
+ /// Registers a setup function for the named HLE service.
+ void RegisterInterfaceForNamedService(std::string name, ServiceInterfaceHandlerFn&& handler);
+
/// Opens a port to a service previously registered with RegisterNamedService.
KClientPort* CreateNamedServicePort(std::string name);
- /// Registers a server session or port with the gobal emulation state, to be freed on shutdown.
- /// This is necessary because we do not emulate processes for HLE sessions and ports.
- void RegisterServerObject(KAutoObject* server_object);
-
- /// Unregisters a server session or port previously registered with RegisterServerSession when
- /// it was destroyed during the current emulation session.
- void UnregisterServerObject(KAutoObject* server_object);
+ /// Accepts a session on a port created by CreateNamedServicePort.
+ void RegisterNamedServiceHandler(std::string name, KServerPort* server_port);
/// Registers all kernel objects with the global emulation state, this is purely for tracking
/// leaks after emulation has been shutdown.
@@ -239,6 +244,12 @@ public:
/// Gets the virtual memory manager for the kernel.
const KMemoryManager& MemoryManager() const;
+ /// Gets the application memory block manager for the kernel.
+ KMemoryBlockSlabManager& GetApplicationMemoryBlockManager();
+
+ /// Gets the application memory block manager for the kernel.
+ const KMemoryBlockSlabManager& GetApplicationMemoryBlockManager() const;
+
/// Gets the shared memory object for HID services.
Kernel::KSharedMemory& GetHidSharedMem();
@@ -345,14 +356,14 @@ public:
return slab_heap_container->thread;
} else if constexpr (std::is_same_v<T, KTransferMemory>) {
return slab_heap_container->transfer_memory;
- } else if constexpr (std::is_same_v<T, KWritableEvent>) {
- return slab_heap_container->writeable_event;
} else if constexpr (std::is_same_v<T, KCodeMemory>) {
return slab_heap_container->code_memory;
} else if constexpr (std::is_same_v<T, KPageBuffer>) {
return slab_heap_container->page_buffer;
} else if constexpr (std::is_same_v<T, KThreadLocalPage>) {
return slab_heap_container->thread_local_page;
+ } else if constexpr (std::is_same_v<T, KSessionRequest>) {
+ return slab_heap_container->session_request;
}
}
@@ -412,10 +423,10 @@ private:
KSlabHeap<KSharedMemoryInfo> shared_memory_info;
KSlabHeap<KThread> thread;
KSlabHeap<KTransferMemory> transfer_memory;
- KSlabHeap<KWritableEvent> writeable_event;
KSlabHeap<KCodeMemory> code_memory;
KSlabHeap<KPageBuffer> page_buffer;
KSlabHeap<KThreadLocalPage> thread_local_page;
+ KSlabHeap<KSessionRequest> session_request;
};
std::unique_ptr<SlabHeapContainer> slab_heap_container;
diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp
index 2e87b4ea4..c8fe42537 100644
--- a/src/core/hle/kernel/service_thread.cpp
+++ b/src/core/hle/kernel/service_thread.cpp
@@ -1,15 +1,18 @@
-// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-#include <condition_variable>
#include <functional>
+#include <map>
#include <mutex>
#include <thread>
#include <vector>
-#include <queue>
#include "common/scope_exit.h"
#include "common/thread.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/kernel/k_event.h"
+#include "core/hle/kernel/k_scoped_resource_reservation.h"
#include "core/hle/kernel/k_session.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h"
@@ -19,101 +22,198 @@ namespace Kernel {
class ServiceThread::Impl final {
public:
- explicit Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name);
+ explicit Impl(KernelCore& kernel, const std::string& service_name);
~Impl();
- void QueueSyncRequest(KSession& session, std::shared_ptr<HLERequestContext>&& context);
+ void WaitAndProcessImpl();
+ void SessionClosed(KServerSession* server_session,
+ std::shared_ptr<SessionRequestManager> manager);
+ void LoopProcess();
+
+ void RegisterServerSession(KServerSession* session,
+ std::shared_ptr<SessionRequestManager> manager);
private:
- std::vector<std::jthread> threads;
- std::queue<std::function<void()>> requests;
- std::mutex queue_mutex;
- std::condition_variable_any condition;
- const std::string service_name;
+ KernelCore& kernel;
+
+ std::jthread m_thread;
+ std::mutex m_session_mutex;
+ std::map<KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions;
+ KEvent* m_wakeup_event;
+ KProcess* m_process;
+ std::atomic<bool> m_shutdown_requested;
+ const std::string m_service_name;
};
-ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name)
- : service_name{name} {
- for (std::size_t i = 0; i < num_threads; ++i) {
- threads.emplace_back([this, &kernel](std::stop_token stop_token) {
- Common::SetCurrentThreadName(std::string{"yuzu:HleService:" + service_name}.c_str());
+void ServiceThread::Impl::WaitAndProcessImpl() {
+ // Create local list of waitable sessions.
+ std::vector<KSynchronizationObject*> objs;
+ std::vector<std::shared_ptr<SessionRequestManager>> managers;
- // Wait for first request before trying to acquire a render context
- {
- std::unique_lock lock{queue_mutex};
- condition.wait(lock, stop_token, [this] { return !requests.empty(); });
- }
+ {
+ // Lock to get the set.
+ std::scoped_lock lk{m_session_mutex};
- if (stop_token.stop_requested()) {
- return;
- }
+ // Reserve the needed quantity.
+ objs.reserve(m_sessions.size() + 1);
+ managers.reserve(m_sessions.size());
- // Allocate a dummy guest thread for this host thread.
- kernel.RegisterHostThread();
+ // Copy to our local list.
+ for (const auto& [session, manager] : m_sessions) {
+ objs.push_back(session);
+ managers.push_back(manager);
+ }
- while (true) {
- std::function<void()> task;
+ // Insert the wakeup event at the end.
+ objs.push_back(&m_wakeup_event->GetReadableEvent());
+ }
- {
- std::unique_lock lock{queue_mutex};
- condition.wait(lock, stop_token, [this] { return !requests.empty(); });
+ // Wait on the list of sessions.
+ s32 index{-1};
+ Result rc = KSynchronizationObject::Wait(kernel, &index, objs.data(),
+ static_cast<s32>(objs.size()), -1);
+ ASSERT(!rc.IsFailure());
+
+ // If this was the wakeup event, clear it and finish.
+ if (index >= static_cast<s64>(objs.size() - 1)) {
+ m_wakeup_event->Clear();
+ return;
+ }
- if (stop_token.stop_requested()) {
- return;
- }
+ // This event is from a server session.
+ auto* server_session = static_cast<KServerSession*>(objs[index]);
+ auto& manager = managers[index];
- if (requests.empty()) {
- continue;
- }
+ // Fetch the HLE request context.
+ std::shared_ptr<HLERequestContext> context;
+ rc = server_session->ReceiveRequest(&context, manager);
- task = std::move(requests.front());
- requests.pop();
- }
+ // If the session was closed, handle that.
+ if (rc == ResultSessionClosed) {
+ SessionClosed(server_session, manager);
- task();
- }
- });
+ // Finish.
+ return;
}
+
+ // TODO: handle other cases
+ ASSERT(rc == ResultSuccess);
+
+ // Perform the request.
+ Result service_rc = manager->CompleteSyncRequest(server_session, *context);
+
+ // Reply to the client.
+ rc = server_session->SendReplyHLE();
+
+ if (rc == ResultSessionClosed || service_rc == IPC::ERR_REMOTE_PROCESS_DEAD) {
+ SessionClosed(server_session, manager);
+ return;
+ }
+
+ // TODO: handle other cases
+ ASSERT(rc == ResultSuccess);
+ ASSERT(service_rc == ResultSuccess);
}
-void ServiceThread::Impl::QueueSyncRequest(KSession& session,
- std::shared_ptr<HLERequestContext>&& context) {
+void ServiceThread::Impl::SessionClosed(KServerSession* server_session,
+ std::shared_ptr<SessionRequestManager> manager) {
{
- std::unique_lock lock{queue_mutex};
+ // Lock to get the set.
+ std::scoped_lock lk{m_session_mutex};
+
+ // Erase the session.
+ ASSERT(m_sessions.erase(server_session) == 1);
+ }
- auto* server_session{&session.GetServerSession()};
+ // Close our reference to the server session.
+ server_session->Close();
+}
- // Open a reference to the session to ensure it is not closes while the service request
- // completes asynchronously.
- server_session->Open();
+void ServiceThread::Impl::LoopProcess() {
+ Common::SetCurrentThreadName(m_service_name.c_str());
- requests.emplace([server_session, context{std::move(context)}]() {
- // Close the reference.
- SCOPE_EXIT({ server_session->Close(); });
+ kernel.RegisterHostThread();
- // Complete the service request.
- server_session->CompleteSyncRequest(*context);
- });
+ while (!m_shutdown_requested.load()) {
+ WaitAndProcessImpl();
}
- condition.notify_one();
+}
+
+void ServiceThread::Impl::RegisterServerSession(KServerSession* server_session,
+ std::shared_ptr<SessionRequestManager> manager) {
+ // Open the server session.
+ server_session->Open();
+
+ {
+ // Lock to get the set.
+ std::scoped_lock lk{m_session_mutex};
+
+ // Insert the session and manager.
+ m_sessions[server_session] = manager;
+ }
+
+ // Signal the wakeup event.
+ m_wakeup_event->Signal();
}
ServiceThread::Impl::~Impl() {
- condition.notify_all();
- for (auto& thread : threads) {
- thread.request_stop();
- thread.join();
+ // Shut down the processing thread.
+ m_shutdown_requested.store(true);
+ m_wakeup_event->Signal();
+ m_thread.join();
+
+ // Lock mutex.
+ m_session_mutex.lock();
+
+ // Close all remaining sessions.
+ for (const auto& [server_session, manager] : m_sessions) {
+ server_session->Close();
}
+
+ // Destroy remaining managers.
+ m_sessions.clear();
+
+ // Close event.
+ m_wakeup_event->GetReadableEvent().Close();
+ m_wakeup_event->Close();
+
+ // Close process.
+ m_process->Close();
+}
+
+ServiceThread::Impl::Impl(KernelCore& kernel_, const std::string& service_name)
+ : kernel{kernel_}, m_service_name{service_name} {
+ // Initialize process.
+ m_process = KProcess::Create(kernel);
+ KProcess::Initialize(m_process, kernel.System(), service_name,
+ KProcess::ProcessType::KernelInternal, kernel.GetSystemResourceLimit());
+
+ // Reserve a new event from the process resource limit
+ KScopedResourceReservation event_reservation(m_process, LimitableResource::Events);
+ ASSERT(event_reservation.Succeeded());
+
+ // Initialize event.
+ m_wakeup_event = KEvent::Create(kernel);
+ m_wakeup_event->Initialize(m_process);
+
+ // Commit the event reservation.
+ event_reservation.Commit();
+
+ // Register the event.
+ KEvent::Register(kernel, m_wakeup_event);
+
+ // Start thread.
+ m_thread = std::jthread([this] { LoopProcess(); });
}
-ServiceThread::ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name)
- : impl{std::make_unique<Impl>(kernel, num_threads, name)} {}
+ServiceThread::ServiceThread(KernelCore& kernel, const std::string& name)
+ : impl{std::make_unique<Impl>(kernel, name)} {}
ServiceThread::~ServiceThread() = default;
-void ServiceThread::QueueSyncRequest(KSession& session,
- std::shared_ptr<HLERequestContext>&& context) {
- impl->QueueSyncRequest(session, std::move(context));
+void ServiceThread::RegisterServerSession(KServerSession* session,
+ std::shared_ptr<SessionRequestManager> manager) {
+ impl->RegisterServerSession(session, manager);
}
} // namespace Kernel
diff --git a/src/core/hle/kernel/service_thread.h b/src/core/hle/kernel/service_thread.h
index c5896f2bd..fb4325531 100644
--- a/src/core/hle/kernel/service_thread.h
+++ b/src/core/hle/kernel/service_thread.h
@@ -11,13 +11,15 @@ namespace Kernel {
class HLERequestContext;
class KernelCore;
class KSession;
+class SessionRequestManager;
class ServiceThread final {
public:
- explicit ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name);
+ explicit ServiceThread(KernelCore& kernel, const std::string& name);
~ServiceThread();
- void QueueSyncRequest(KSession& session, std::shared_ptr<HLERequestContext>&& context);
+ void RegisterServerSession(KServerSession* session,
+ std::shared_ptr<SessionRequestManager> manager);
private:
class Impl;
diff --git a/src/core/hle/kernel/slab_helpers.h b/src/core/hle/kernel/slab_helpers.h
index 299a981a8..06b51e919 100644
--- a/src/core/hle/kernel/slab_helpers.h
+++ b/src/core/hle/kernel/slab_helpers.h
@@ -24,7 +24,7 @@ public:
}
static Derived* Allocate(KernelCore& kernel) {
- return kernel.SlabHeap<Derived>().Allocate();
+ return kernel.SlabHeap<Derived>().Allocate(kernel);
}
static void Free(KernelCore& kernel, Derived* obj) {
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 27e5a805d..4c819f4b6 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -24,17 +24,18 @@
#include "core/hle/kernel/k_memory_block.h"
#include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_page_table.h"
+#include "core/hle/kernel/k_port.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_scoped_resource_reservation.h"
+#include "core/hle/kernel/k_session.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_synchronization_object.h"
#include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/k_thread_queue.h"
#include "core/hle/kernel/k_transfer_memory.h"
-#include "core/hle/kernel/k_writable_event.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_core.h"
#include "core/hle/kernel/svc.h"
@@ -256,6 +257,93 @@ static Result UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u3
return UnmapMemory(system, dst_addr, src_addr, size);
}
+template <typename T>
+Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, u64 name) {
+ auto& process = *system.CurrentProcess();
+ auto& handle_table = process.GetHandleTable();
+
+ // Declare the session we're going to allocate.
+ T* session;
+
+ // Reserve a new session from the process resource limit.
+ // FIXME: LimitableResource_SessionCountMax
+ KScopedResourceReservation session_reservation(&process, LimitableResource::Sessions);
+ if (session_reservation.Succeeded()) {
+ session = T::Create(system.Kernel());
+ } else {
+ return ResultLimitReached;
+
+ // // We couldn't reserve a session. Check that we support dynamically expanding the
+ // // resource limit.
+ // R_UNLESS(process.GetResourceLimit() ==
+ // &system.Kernel().GetSystemResourceLimit(), ResultLimitReached);
+ // R_UNLESS(KTargetSystem::IsDynamicResourceLimitsEnabled(), ResultLimitReached());
+
+ // // Try to allocate a session from unused slab memory.
+ // session = T::CreateFromUnusedSlabMemory();
+ // R_UNLESS(session != nullptr, ResultLimitReached);
+ // ON_RESULT_FAILURE { session->Close(); };
+
+ // // If we're creating a KSession, we want to add two KSessionRequests to the heap, to
+ // // prevent request exhaustion.
+ // // NOTE: Nintendo checks if session->DynamicCast<KSession *>() != nullptr, but there's
+ // // no reason to not do this statically.
+ // if constexpr (std::same_as<T, KSession>) {
+ // for (size_t i = 0; i < 2; i++) {
+ // KSessionRequest* request = KSessionRequest::CreateFromUnusedSlabMemory();
+ // R_UNLESS(request != nullptr, ResultLimitReached);
+ // request->Close();
+ // }
+ // }
+
+ // We successfully allocated a session, so add the object we allocated to the resource
+ // limit.
+ // system.Kernel().GetSystemResourceLimit().Reserve(LimitableResource::Sessions, 1);
+ }
+
+ // Check that we successfully created a session.
+ R_UNLESS(session != nullptr, ResultOutOfResource);
+
+ // Initialize the session.
+ session->Initialize(nullptr, fmt::format("{}", name));
+
+ // Commit the session reservation.
+ session_reservation.Commit();
+
+ // Ensure that we clean up the session (and its only references are handle table) on function
+ // end.
+ SCOPE_EXIT({
+ session->GetClientSession().Close();
+ session->GetServerSession().Close();
+ });
+
+ // Register the session.
+ T::Register(system.Kernel(), session);
+
+ // Add the server session to the handle table.
+ R_TRY(handle_table.Add(out_server, &session->GetServerSession()));
+
+ // Add the client session to the handle table.
+ const auto result = handle_table.Add(out_client, &session->GetClientSession());
+
+ if (!R_SUCCEEDED(result)) {
+ // Ensure that we maintaing a clean handle state on exit.
+ handle_table.Remove(*out_server);
+ }
+
+ return result;
+}
+
+static Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client,
+ u32 is_light, u64 name) {
+ if (is_light) {
+ // return CreateSession<KLightSession>(system, out_server, out_client, name);
+ return ResultUnknown;
+ } else {
+ return CreateSession<KSession>(system, out_server, out_client, name);
+ }
+}
+
/// Connect to an OS service given the port name, returns the handle to the port to out
static Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) {
auto& memory = system.Memory();
@@ -296,7 +384,8 @@ static Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_n
// Create a session.
KClientSession* session{};
R_TRY(port->CreateSession(std::addressof(session)));
- port->Close();
+
+ kernel.RegisterNamedServiceHandler(port_name, &port->GetParent()->GetServerPort());
// Register the session in the table, close the extra reference.
handle_table.Register(*out, session);
@@ -313,7 +402,7 @@ static Result ConnectToNamedPort32(Core::System& system, Handle* out_handle,
return ConnectToNamedPort(system, out_handle, port_name_address);
}
-/// Makes a blocking IPC call to an OS service.
+/// Makes a blocking IPC call to a service.
static Result SendSyncRequest(Core::System& system, Handle handle) {
auto& kernel = system.Kernel();
@@ -327,22 +416,75 @@ static Result SendSyncRequest(Core::System& system, Handle handle) {
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
- {
- KScopedSchedulerLock lock(kernel);
-
- // This is a synchronous request, so we should wait for our request to complete.
- GetCurrentThread(kernel).BeginWait(std::addressof(wait_queue));
- GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
- session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(), system.CoreTiming());
- }
-
- return GetCurrentThread(kernel).GetWaitResult();
+ return session->SendSyncRequest();
}
static Result SendSyncRequest32(Core::System& system, Handle handle) {
return SendSyncRequest(system, handle);
}
+static Result ReplyAndReceive(Core::System& system, s32* out_index, Handle* handles,
+ s32 num_handles, Handle reply_target, s64 timeout_ns) {
+ auto& kernel = system.Kernel();
+ auto& handle_table = GetCurrentThread(kernel).GetOwnerProcess()->GetHandleTable();
+
+ // Convert handle list to object table.
+ std::vector<KSynchronizationObject*> objs(num_handles);
+ R_UNLESS(
+ handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, num_handles),
+ ResultInvalidHandle);
+
+ // Ensure handles are closed when we're done.
+ SCOPE_EXIT({
+ for (auto i = 0; i < num_handles; ++i) {
+ objs[i]->Close();
+ }
+ });
+
+ // Reply to the target, if one is specified.
+ if (reply_target != InvalidHandle) {
+ KScopedAutoObject session = handle_table.GetObject<KServerSession>(reply_target);
+ R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
+
+ // If we fail to reply, we want to set the output index to -1.
+ // ON_RESULT_FAILURE { *out_index = -1; };
+
+ // Send the reply.
+ // R_TRY(session->SendReply());
+
+ Result rc = session->SendReply();
+ if (!R_SUCCEEDED(rc)) {
+ *out_index = -1;
+ return rc;
+ }
+ }
+
+ // Wait for a message.
+ while (true) {
+ // Wait for an object.
+ s32 index;
+ Result result = KSynchronizationObject::Wait(kernel, &index, objs.data(),
+ static_cast<s32>(objs.size()), timeout_ns);
+ if (result == ResultTimedOut) {
+ return result;
+ }
+
+ // Receive the request.
+ if (R_SUCCEEDED(result)) {
+ KServerSession* session = objs[index]->DynamicCast<KServerSession*>();
+ if (session != nullptr) {
+ result = session->ReceiveRequest();
+ if (result == ResultNotFound) {
+ continue;
+ }
+ }
+ }
+
+ *out_index = index;
+ return result;
+ }
+}
+
/// Get the ID for the specified thread.
static Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) {
// Get the thread from its handle.
@@ -610,8 +752,8 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) {
}
system.GetReporter().SaveSvcBreakReport(
- static_cast<u32>(break_reason.break_type.Value()), break_reason.signal_debugger, info1,
- info2, has_dumped_buffer ? std::make_optional(debug_buffer) : std::nullopt);
+ static_cast<u32>(break_reason.break_type.Value()), break_reason.signal_debugger.As<bool>(),
+ info1, info2, has_dumped_buffer ? std::make_optional(debug_buffer) : std::nullopt);
if (!break_reason.signal_debugger) {
LOG_CRITICAL(
@@ -792,7 +934,7 @@ static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle han
return ResultSuccess;
case GetInfoType::UserExceptionContextAddr:
- *result = process->GetTLSRegionAddress();
+ *result = process->GetProcessLocalRegionAddress();
return ResultSuccess;
case GetInfoType::TotalPhysicalMemoryAvailableWithoutSystemResource:
@@ -1747,7 +1889,7 @@ static void ExitProcess(Core::System& system) {
auto* current_process = system.Kernel().CurrentProcess();
LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID());
- ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running,
+ ASSERT_MSG(current_process->GetState() == KProcess::State::Running,
"Process has already exited");
system.Exit();
@@ -2303,11 +2445,11 @@ static Result SignalEvent(Core::System& system, Handle event_handle) {
// Get the current handle table.
const KHandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
- // Get the writable event.
- KScopedAutoObject writable_event = handle_table.GetObject<KWritableEvent>(event_handle);
- R_UNLESS(writable_event.IsNotNull(), ResultInvalidHandle);
+ // Get the event.
+ KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
+ R_UNLESS(event.IsNotNull(), ResultInvalidHandle);
- return writable_event->Signal();
+ return event->Signal();
}
static Result SignalEvent32(Core::System& system, Handle event_handle) {
@@ -2322,9 +2464,9 @@ static Result ClearEvent(Core::System& system, Handle event_handle) {
// Try to clear the writable event.
{
- KScopedAutoObject writable_event = handle_table.GetObject<KWritableEvent>(event_handle);
- if (writable_event.IsNotNull()) {
- return writable_event->Clear();
+ KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
+ if (event.IsNotNull()) {
+ return event->Clear();
}
}
@@ -2362,24 +2504,24 @@ static Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_r
R_UNLESS(event != nullptr, ResultOutOfResource);
// Initialize the event.
- event->Initialize("CreateEvent", kernel.CurrentProcess());
+ event->Initialize(kernel.CurrentProcess());
// Commit the thread reservation.
event_reservation.Commit();
// Ensure that we clean up the event (and its only references are handle table) on function end.
SCOPE_EXIT({
- event->GetWritableEvent().Close();
event->GetReadableEvent().Close();
+ event->Close();
});
// Register the event.
KEvent::Register(kernel, event);
- // Add the writable event to the handle table.
- R_TRY(handle_table.Add(out_write, std::addressof(event->GetWritableEvent())));
+ // Add the event to the handle table.
+ R_TRY(handle_table.Add(out_write, event));
- // Add the writable event to the handle table.
+ // Ensure that we maintaing a clean handle state on exit.
auto handle_guard = SCOPE_GUARD({ handle_table.Remove(*out_write); });
// Add the readable event to the handle table.
@@ -2416,7 +2558,7 @@ static Result GetProcessInfo(Core::System& system, u64* out, Handle process_hand
return ResultInvalidEnumValue;
}
- *out = static_cast<u64>(process->GetStatus());
+ *out = static_cast<u64>(process->GetState());
return ResultSuccess;
}
@@ -2860,10 +3002,10 @@ static const FunctionDef SVC_Table_64[] = {
{0x3D, SvcWrap64<ChangeKernelTraceState>, "ChangeKernelTraceState"},
{0x3E, nullptr, "Unknown3e"},
{0x3F, nullptr, "Unknown3f"},
- {0x40, nullptr, "CreateSession"},
+ {0x40, SvcWrap64<CreateSession>, "CreateSession"},
{0x41, nullptr, "AcceptSession"},
{0x42, nullptr, "ReplyAndReceiveLight"},
- {0x43, nullptr, "ReplyAndReceive"},
+ {0x43, SvcWrap64<ReplyAndReceive>, "ReplyAndReceive"},
{0x44, nullptr, "ReplyAndReceiveWithUserBuffer"},
{0x45, SvcWrap64<CreateEvent>, "CreateEvent"},
{0x46, nullptr, "MapIoRegion"},
diff --git a/src/core/hle/kernel/svc_common.h b/src/core/hle/kernel/svc_common.h
index 95750c3eb..85506710e 100644
--- a/src/core/hle/kernel/svc_common.h
+++ b/src/core/hle/kernel/svc_common.h
@@ -14,8 +14,11 @@ namespace Kernel::Svc {
using namespace Common::Literals;
-constexpr s32 ArgumentHandleCountMax = 0x40;
-constexpr u32 HandleWaitMask{1u << 30};
+constexpr inline s32 ArgumentHandleCountMax = 0x40;
+
+constexpr inline u32 HandleWaitMask = 1u << 30;
+
+constexpr inline s64 WaitInfinite = -1;
constexpr inline std::size_t HeapSizeAlignment = 2_MiB;
diff --git a/src/core/hle/kernel/svc_types.h b/src/core/hle/kernel/svc_types.h
index 79e15183a..abb9847fe 100644
--- a/src/core/hle/kernel/svc_types.h
+++ b/src/core/hle/kernel/svc_types.h
@@ -95,6 +95,19 @@ constexpr inline s32 IdealCoreNoUpdate = -3;
constexpr inline s32 LowestThreadPriority = 63;
constexpr inline s32 HighestThreadPriority = 0;
+constexpr inline s32 SystemThreadPriorityHighest = 16;
+
+enum class ProcessState : u32 {
+ Created = 0,
+ CreatedAttached = 1,
+ Running = 2,
+ Crashed = 3,
+ RunningAttached = 4,
+ Terminating = 5,
+ Terminated = 6,
+ DebugBreak = 7,
+};
+
constexpr inline size_t ThreadLocalRegionSize = 0x200;
} // namespace Kernel::Svc
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index 4bc49087e..272c54cf7 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -8,6 +8,7 @@
#include "core/core.h"
#include "core/hle/kernel/svc_types.h"
#include "core/hle/result.h"
+#include "core/memory.h"
namespace Kernel {
@@ -346,6 +347,37 @@ void SvcWrap64(Core::System& system) {
FuncReturn(system, retval);
}
+// Used by CreateSession
+template <Result func(Core::System&, Handle*, Handle*, u32, u64)>
+void SvcWrap64(Core::System& system) {
+ Handle param_1 = 0;
+ Handle param_2 = 0;
+ const u32 retval = func(system, &param_1, &param_2, static_cast<u32>(Param(system, 2)),
+ static_cast<u32>(Param(system, 3)))
+ .raw;
+
+ system.CurrentArmInterface().SetReg(1, param_1);
+ system.CurrentArmInterface().SetReg(2, param_2);
+ FuncReturn(system, retval);
+}
+
+// Used by ReplyAndReceive
+template <Result func(Core::System&, s32*, Handle*, s32, Handle, s64)>
+void SvcWrap64(Core::System& system) {
+ s32 param_1 = 0;
+ s32 num_handles = static_cast<s32>(Param(system, 2));
+
+ std::vector<Handle> handles(num_handles);
+ system.Memory().ReadBlock(Param(system, 1), handles.data(), num_handles * sizeof(Handle));
+
+ const u32 retval = func(system, &param_1, handles.data(), num_handles,
+ static_cast<s32>(Param(system, 3)), static_cast<s64>(Param(system, 4)))
+ .raw;
+
+ system.CurrentArmInterface().SetReg(1, param_1);
+ FuncReturn(system, retval);
+}
+
// Used by WaitForAddress
template <Result func(Core::System&, u64, Svc::ArbitrationType, s32, s64)>
void SvcWrap64(Core::System& system) {
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index 47a1b829b..ef4b2d417 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/bit_field.h"
+#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/expected.h"
@@ -130,6 +131,18 @@ union Result {
[[nodiscard]] constexpr bool IsError() const {
return !IsSuccess();
}
+
+ [[nodiscard]] constexpr bool IsFailure() const {
+ return !IsSuccess();
+ }
+
+ [[nodiscard]] constexpr u32 GetInnerValue() const {
+ return static_cast<u32>(module.Value()) | (description << module.bits);
+ }
+
+ [[nodiscard]] constexpr bool Includes(Result result) const {
+ return GetInnerValue() == result.GetInnerValue();
+ }
};
static_assert(std::is_trivial_v<Result>);
@@ -349,19 +362,115 @@ private:
} \
} while (false)
-#define R_SUCCEEDED(res) (res.IsSuccess())
+#define R_SUCCEEDED(res) (static_cast<Result>(res).IsSuccess())
+#define R_FAILED(res) (static_cast<Result>(res).IsFailure())
-/// Evaluates a boolean expression, and succeeds if that expression is true.
-#define R_SUCCEED_IF(expr) R_UNLESS(!(expr), ResultSuccess)
+namespace ResultImpl {
+template <auto EvaluateResult, class F>
+class ScopedResultGuard {
+ YUZU_NON_COPYABLE(ScopedResultGuard);
+ YUZU_NON_MOVEABLE(ScopedResultGuard);
+
+private:
+ Result& m_ref;
+ F m_f;
+
+public:
+ constexpr ScopedResultGuard(Result& ref, F f) : m_ref(ref), m_f(std::move(f)) {}
+ constexpr ~ScopedResultGuard() {
+ if (EvaluateResult(m_ref)) {
+ m_f();
+ }
+ }
+};
+
+template <auto EvaluateResult>
+class ResultReferenceForScopedResultGuard {
+private:
+ Result& m_ref;
+
+public:
+ constexpr ResultReferenceForScopedResultGuard(Result& r) : m_ref(r) {}
+ constexpr operator Result&() const {
+ return m_ref;
+ }
+};
+
+template <auto EvaluateResult, typename F>
+constexpr ScopedResultGuard<EvaluateResult, F> operator+(
+ ResultReferenceForScopedResultGuard<EvaluateResult> ref, F&& f) {
+ return ScopedResultGuard<EvaluateResult, F>(static_cast<Result&>(ref), std::forward<F>(f));
+}
+
+constexpr bool EvaluateResultSuccess(const Result& r) {
+ return R_SUCCEEDED(r);
+}
+constexpr bool EvaluateResultFailure(const Result& r) {
+ return R_FAILED(r);
+}
+
+template <typename T>
+constexpr void UpdateCurrentResultReference(T result_reference, Result result) = delete;
+// Intentionally not defined
+
+template <>
+constexpr void UpdateCurrentResultReference<Result&>(Result& result_reference, Result result) {
+ result_reference = result;
+}
+
+template <>
+constexpr void UpdateCurrentResultReference<const Result>(Result result_reference, Result result) {}
+} // namespace ResultImpl
+
+#define DECLARE_CURRENT_RESULT_REFERENCE_AND_STORAGE(COUNTER_VALUE) \
+ [[maybe_unused]] constexpr bool HasPrevRef_##COUNTER_VALUE = \
+ std::same_as<decltype(__TmpCurrentResultReference), Result&>; \
+ [[maybe_unused]] auto& PrevRef_##COUNTER_VALUE = __TmpCurrentResultReference; \
+ [[maybe_unused]] Result __tmp_result_##COUNTER_VALUE = ResultSuccess; \
+ Result& __TmpCurrentResultReference = \
+ HasPrevRef_##COUNTER_VALUE ? PrevRef_##COUNTER_VALUE : __tmp_result_##COUNTER_VALUE
+
+#define ON_RESULT_RETURN_IMPL(...) \
+ static_assert(std::same_as<decltype(__TmpCurrentResultReference), Result&>); \
+ auto RESULT_GUARD_STATE_##__COUNTER__ = \
+ ResultImpl::ResultReferenceForScopedResultGuard<__VA_ARGS__>( \
+ __TmpCurrentResultReference) + \
+ [&]()
+
+#define ON_RESULT_FAILURE_2 ON_RESULT_RETURN_IMPL(ResultImpl::EvaluateResultFailure)
+
+#define ON_RESULT_FAILURE \
+ DECLARE_CURRENT_RESULT_REFERENCE_AND_STORAGE(__COUNTER__); \
+ ON_RESULT_FAILURE_2
+
+#define ON_RESULT_SUCCESS_2 ON_RESULT_RETURN_IMPL(ResultImpl::EvaluateResultSuccess)
+
+#define ON_RESULT_SUCCESS \
+ DECLARE_CURRENT_RESULT_REFERENCE_AND_STORAGE(__COUNTER__); \
+ ON_RESULT_SUCCESS_2
+
+constexpr inline Result __TmpCurrentResultReference = ResultSuccess;
+
+/// Returns a result.
+#define R_RETURN(res_expr) \
+ { \
+ const Result _tmp_r_throw_rc = (res_expr); \
+ ResultImpl::UpdateCurrentResultReference<decltype(__TmpCurrentResultReference)>( \
+ __TmpCurrentResultReference, _tmp_r_throw_rc); \
+ return _tmp_r_throw_rc; \
+ }
+
+/// Returns ResultSuccess()
+#define R_SUCCEED() R_RETURN(ResultSuccess)
+
+/// Throws a result.
+#define R_THROW(res_expr) R_RETURN(res_expr)
/// Evaluates a boolean expression, and returns a result unless that expression is true.
#define R_UNLESS(expr, res) \
{ \
if (!(expr)) { \
- if (res.IsError()) { \
- LOG_ERROR(Kernel, "Failed with result: {}", res.raw); \
- } \
- return res; \
+ R_THROW(res); \
} \
}
@@ -369,7 +478,10 @@ private:
#define R_TRY(res_expr) \
{ \
const auto _tmp_r_try_rc = (res_expr); \
- if (_tmp_r_try_rc.IsError()) { \
- return _tmp_r_try_rc; \
+ if (R_FAILED(_tmp_r_try_rc)) { \
+ R_THROW(_tmp_r_try_rc); \
} \
}
+
+/// Evaluates a boolean expression, and succeeds if that expression is true.
+#define R_SUCCEED_IF(expr) R_UNLESS(!(expr), ResultSuccess)
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index bb838e285..85a3f0802 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -512,10 +512,11 @@ protected:
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
public:
- explicit IManagerForApplication(Core::System& system_, Common::UUID user_id_)
+ explicit IManagerForApplication(Core::System& system_,
+ const std::shared_ptr<ProfileManager>& profile_manager_)
: ServiceFramework{system_, "IManagerForApplication"},
ensure_token_id{std::make_shared<EnsureTokenIdCacheAsyncInterface>(system)},
- user_id{user_id_} {
+ profile_manager{profile_manager_} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
@@ -545,7 +546,7 @@ private:
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
- rb.PushRaw<u64>(user_id.Hash());
+ rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash());
}
void EnsureIdTokenCacheAsync(Kernel::HLERequestContext& ctx) {
@@ -575,17 +576,20 @@ private:
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
- rb.PushRaw<u64>(user_id.Hash());
+ rb.PushRaw<u64>(profile_manager->GetLastOpenedUser().Hash());
}
void StoreOpenContext(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_ACC, "(STUBBED) called");
+ LOG_DEBUG(Service_ACC, "called");
+
+ profile_manager->StoreOpenedUsers();
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
std::shared_ptr<EnsureTokenIdCacheAsyncInterface> ensure_token_id{};
- Common::UUID user_id{};
+ std::shared_ptr<ProfileManager> profile_manager;
};
// 6.0.0+
@@ -790,7 +794,7 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
LOG_DEBUG(Service_ACC, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
- rb.PushIpcInterface<IManagerForApplication>(system, profile_manager->GetLastOpenedUser());
+ rb.PushIpcInterface<IManagerForApplication>(system, profile_manager);
}
void Module::Interface::IsUserAccountSwitchLocked(Kernel::HLERequestContext& ctx) {
@@ -849,22 +853,10 @@ void Module::Interface::ListQualifiedUsers(Kernel::HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
-void Module::Interface::LoadOpenContext(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_ACC, "(STUBBED) called");
-
- // This is similar to GetBaasAccountManagerForApplication
- // This command is used concurrently with ListOpenContextStoredUsers
- // TODO: Find the differences between this and GetBaasAccountManagerForApplication
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(ResultSuccess);
- rb.PushIpcInterface<IManagerForApplication>(system, profile_manager->GetLastOpenedUser());
-}
-
void Module::Interface::ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_ACC, "(STUBBED) called");
+ LOG_DEBUG(Service_ACC, "called");
- // TODO(ogniK): Handle open contexts
- ctx.WriteBuffer(profile_manager->GetOpenUsers());
+ ctx.WriteBuffer(profile_manager->GetStoredOpenedUsers());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h
index 1621e7c0a..9411b0b92 100644
--- a/src/core/hle/service/acc/acc.h
+++ b/src/core/hle/service/acc/acc.h
@@ -35,7 +35,6 @@ public:
void InitializeApplicationInfoV2(Kernel::HLERequestContext& ctx);
void GetProfileEditor(Kernel::HLERequestContext& ctx);
void ListQualifiedUsers(Kernel::HLERequestContext& ctx);
- void LoadOpenContext(Kernel::HLERequestContext& ctx);
void ListOpenContextStoredUsers(Kernel::HLERequestContext& ctx);
void StoreSaveDataThumbnailApplication(Kernel::HLERequestContext& ctx);
void StoreSaveDataThumbnailSystem(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp
index 65023b8c2..54844bfe7 100644
--- a/src/core/hle/service/acc/acc_u0.cpp
+++ b/src/core/hle/service/acc/acc_u0.cpp
@@ -28,7 +28,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager>
{110, &ACC_U0::StoreSaveDataThumbnailApplication, "StoreSaveDataThumbnail"},
{111, nullptr, "ClearSaveDataThumbnail"},
{120, nullptr, "CreateGuestLoginRequest"},
- {130, &ACC_U0::LoadOpenContext, "LoadOpenContext"}, // 5.0.0+
+ {130, nullptr, "LoadOpenContext"}, // 5.0.0+
{131, &ACC_U0::ListOpenContextStoredUsers, "ListOpenContextStoredUsers"}, // 6.0.0+
{140, &ACC_U0::InitializeApplicationInfoRestricted, "InitializeApplicationInfoRestricted"}, // 6.0.0+
{141, &ACC_U0::ListQualifiedUsers, "ListQualifiedUsers"}, // 6.0.0+
diff --git a/src/core/hle/service/acc/async_context.cpp b/src/core/hle/service/acc/async_context.cpp
index c85b2e43a..713689d8f 100644
--- a/src/core/hle/service/acc/async_context.cpp
+++ b/src/core/hle/service/acc/async_context.cpp
@@ -64,7 +64,7 @@ void IAsyncContext::GetResult(Kernel::HLERequestContext& ctx) {
void IAsyncContext::MarkComplete() {
is_complete.store(true);
- completion_event->GetWritableEvent().Signal();
+ completion_event->Signal();
}
} // namespace Service::Account
diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp
index a58da4d5f..481e0d141 100644
--- a/src/core/hle/service/acc/profile_manager.cpp
+++ b/src/core/hle/service/acc/profile_manager.cpp
@@ -261,6 +261,31 @@ UUID ProfileManager::GetLastOpenedUser() const {
return last_opened_user;
}
+/// Gets the list of stored opened users.
+UserIDArray ProfileManager::GetStoredOpenedUsers() const {
+ UserIDArray output{};
+ std::ranges::transform(stored_opened_profiles, output.begin(), [](const ProfileInfo& p) {
+ if (p.is_open)
+ return p.user_uuid;
+ return Common::InvalidUUID;
+ });
+ std::stable_partition(output.begin(), output.end(),
+ [](const UUID& uuid) { return uuid.IsValid(); });
+ return output;
+}
+
+/// Captures the opened users, which can be queried across process launches with
+/// ListOpenContextStoredUsers.
+void ProfileManager::StoreOpenedUsers() {
+ size_t profile_index{};
+ stored_opened_profiles = {};
+ std::for_each(profiles.begin(), profiles.end(), [&](const auto& profile) {
+ if (profile.is_open) {
+ stored_opened_profiles[profile_index++] = profile;
+ }
+ });
+}
+
/// Return the users profile base and the unknown arbitary data.
bool ProfileManager::GetProfileBaseAndData(std::optional<std::size_t> index, ProfileBase& profile,
UserData& data) const {
diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h
index 135f7d0d5..993a5a57a 100644
--- a/src/core/hle/service/acc/profile_manager.h
+++ b/src/core/hle/service/acc/profile_manager.h
@@ -86,6 +86,8 @@ public:
UserIDArray GetOpenUsers() const;
UserIDArray GetAllUsers() const;
Common::UUID GetLastOpenedUser() const;
+ UserIDArray GetStoredOpenedUsers() const;
+ void StoreOpenedUsers();
bool CanSystemRegisterUser() const;
@@ -101,6 +103,7 @@ private:
bool RemoveProfileAtIndex(std::size_t index);
std::array<ProfileInfo, MAX_USERS> profiles{};
+ std::array<ProfileInfo, MAX_USERS> stored_opened_profiles{};
std::size_t user_count{};
Common::UUID last_opened_user{};
};
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 6fb7e198e..8ea7fd760 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -299,7 +299,7 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
{100, &ISelfController::SetAlbumImageTakenNotificationEnabled, "SetAlbumImageTakenNotificationEnabled"},
{110, nullptr, "SetApplicationAlbumUserData"},
{120, &ISelfController::SaveCurrentScreenshot, "SaveCurrentScreenshot"},
- {130, nullptr, "SetRecordVolumeMuted"},
+ {130, &ISelfController::SetRecordVolumeMuted, "SetRecordVolumeMuted"},
{1000, nullptr, "GetDebugStorageChannel"},
};
// clang-format on
@@ -316,7 +316,7 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
accumulated_suspended_tick_changed_event =
service_context.CreateEvent("ISelfController:AccumulatedSuspendedTickChangedEvent");
- accumulated_suspended_tick_changed_event->GetWritableEvent().Signal();
+ accumulated_suspended_tick_changed_event->Signal();
}
ISelfController::~ISelfController() {
@@ -378,7 +378,7 @@ void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) {
void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called");
- launchable_event->GetWritableEvent().Signal();
+ launchable_event->Signal();
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
@@ -597,6 +597,17 @@ void ISelfController::SaveCurrentScreenshot(Kernel::HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
+void ISelfController::SetRecordVolumeMuted(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+
+ const auto is_record_volume_muted = rp.Pop<bool>();
+
+ LOG_WARNING(Service_AM, "(STUBBED) called. is_record_volume_muted={}", is_record_volume_muted);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
AppletMessageQueue::AppletMessageQueue(Core::System& system)
: service_context{system, "AppletMessageQueue"} {
on_new_message = service_context.CreateEvent("AMMessageQueue:OnMessageReceived");
@@ -618,18 +629,18 @@ Kernel::KReadableEvent& AppletMessageQueue::GetOperationModeChangedEvent() {
void AppletMessageQueue::PushMessage(AppletMessage msg) {
messages.push(msg);
- on_new_message->GetWritableEvent().Signal();
+ on_new_message->Signal();
}
AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
if (messages.empty()) {
- on_new_message->GetWritableEvent().Clear();
+ on_new_message->Clear();
return AppletMessage::None;
}
auto msg = messages.front();
messages.pop();
if (messages.empty()) {
- on_new_message->GetWritableEvent().Clear();
+ on_new_message->Clear();
}
return msg;
}
@@ -653,7 +664,7 @@ void AppletMessageQueue::FocusStateChanged() {
void AppletMessageQueue::OperationModeChanged() {
PushMessage(AppletMessage::OperationModeChanged);
PushMessage(AppletMessage::PerformanceModeChanged);
- on_operation_mode_changed->GetWritableEvent().Signal();
+ on_operation_mode_changed->Signal();
}
ICommonStateGetter::ICommonStateGetter(Core::System& system_,
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index bb75c6281..a0fbfcfc5 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -182,6 +182,7 @@ private:
void GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequestContext& ctx);
void SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestContext& ctx);
void SaveCurrentScreenshot(Kernel::HLERequestContext& ctx);
+ void SetRecordVolumeMuted(Kernel::HLERequestContext& ctx);
enum class ScreenshotPermission : u32 {
Inherit = 0,
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index b5b8e4cad..7062df21c 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -65,7 +65,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
auto out = std::move(out_channel.front());
out_channel.pop_front();
- pop_out_data_event->GetWritableEvent().Clear();
+ pop_out_data_event->Clear();
return out;
}
@@ -84,7 +84,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() {
auto out = std::move(out_interactive_channel.front());
out_interactive_channel.pop_front();
- pop_interactive_out_data_event->GetWritableEvent().Clear();
+ pop_interactive_out_data_event->Clear();
return out;
}
@@ -103,7 +103,7 @@ void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storag
void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) {
out_channel.emplace_back(std::move(storage));
- pop_out_data_event->GetWritableEvent().Signal();
+ pop_out_data_event->Signal();
}
void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) {
@@ -112,11 +112,11 @@ void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& s
void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) {
out_interactive_channel.emplace_back(std::move(storage));
- pop_interactive_out_data_event->GetWritableEvent().Signal();
+ pop_interactive_out_data_event->Signal();
}
void AppletDataBroker::SignalStateChanged() {
- state_changed_event->GetWritableEvent().Signal();
+ state_changed_event->Signal();
switch (applet_mode) {
case LibraryAppletMode::AllForeground:
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index e78a57657..12c6a5b1a 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -164,7 +164,7 @@ protected:
u32_le size;
u32_le library_version;
u32_le theme_color;
- u8 play_startup_sound;
+ bool play_startup_sound;
u64_le system_tick;
};
static_assert(sizeof(CommonArguments) == 0x20, "CommonArguments has incorrect size.");
diff --git a/src/core/hle/service/audio/audctl.cpp b/src/core/hle/service/audio/audctl.cpp
index 4a2ae5f88..5abf22ba4 100644
--- a/src/core/hle/service/audio/audctl.cpp
+++ b/src/core/hle/service/audio/audctl.cpp
@@ -45,9 +45,25 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} {
{32, nullptr, "GetActiveOutputTarget"},
{33, nullptr, "GetTargetDeviceInfo"},
{34, nullptr, "AcquireTargetNotification"},
+ {35, nullptr, "SetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
+ {36, nullptr, "GetHearingProtectionSafeguardTimerRemainingTimeForDebug"},
+ {37, nullptr, "SetHearingProtectionSafeguardEnabled"},
+ {38, nullptr, "IsHearingProtectionSafeguardEnabled"},
+ {39, nullptr, "IsHearingProtectionSafeguardMonitoringOutputForDebug"},
+ {40, nullptr, "GetSystemInformationForDebug"},
+ {41, nullptr, "SetVolumeButtonLongPressTime"},
+ {42, nullptr, "SetNativeVolumeForDebug"},
{10000, nullptr, "NotifyAudioOutputTargetForPlayReport"},
{10001, nullptr, "NotifyAudioOutputChannelCountForPlayReport"},
{10002, nullptr, "NotifyUnsupportedUsbOutputDeviceAttachedForPlayReport"},
+ {10100, nullptr, "GetAudioVolumeDataForPlayReport"},
+ {10101, nullptr, "BindAudioVolumeUpdateEventForPlayReport"},
+ {10102, nullptr, "BindAudioOutputTargetUpdateEventForPlayReport"},
+ {10103, nullptr, "GetAudioOutputTargetForPlayReport"},
+ {10104, nullptr, "GetAudioOutputChannelCountForPlayReport"},
+ {10105, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
+ {10106, nullptr, "GetDefaultAudioOutputTargetForPlayReport"},
+ {50000, nullptr, "SetAnalogInputBoostGainForPrototyping"},
};
// clang-format on
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp
index 48a9a73a0..608925dfc 100644
--- a/src/core/hle/service/audio/audin_u.cpp
+++ b/src/core/hle/service/audio/audin_u.cpp
@@ -17,7 +17,7 @@ using namespace AudioCore::AudioIn;
class IAudioIn final : public ServiceFramework<IAudioIn> {
public:
explicit IAudioIn(Core::System& system_, Manager& manager, size_t session_id,
- std::string& device_name, const AudioInParameter& in_params, u32 handle,
+ const std::string& device_name, const AudioInParameter& in_params, u32 handle,
u64 applet_resource_user_id)
: ServiceFramework{system_, "IAudioIn"},
service_context{system_, "IAudioIn"}, event{service_context.CreateEvent("AudioInEvent")},
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 49c092301..122290c6a 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -24,7 +24,7 @@ using namespace AudioCore::AudioOut;
class IAudioOut final : public ServiceFramework<IAudioOut> {
public:
explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager,
- size_t session_id, std::string& device_name,
+ size_t session_id, const std::string& device_name,
const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id)
: ServiceFramework{system_, "IAudioOut", ServiceThreadType::CreateNew},
service_context{system_, "IAudioOut"}, event{service_context.CreateEvent(
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 6fb07c37d..13423dca6 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -52,6 +52,8 @@ public:
{9, &IAudioRenderer::GetRenderingTimeLimit, "GetRenderingTimeLimit"},
{10, &IAudioRenderer::RequestUpdate, "RequestUpdateAuto"},
{11, nullptr, "ExecuteAudioRendererRendering"},
+ {12, &IAudioRenderer::SetVoiceDropParameter, "SetVoiceDropParameter"},
+ {13, &IAudioRenderer::GetVoiceDropParameter, "GetVoiceDropParameter"},
};
// clang-format on
RegisterHandlers(functions);
@@ -205,6 +207,30 @@ private:
LOG_DEBUG(Service_Audio, "called");
}
+ void SetVoiceDropParameter(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_Audio, "called");
+
+ IPC::RequestParser rp{ctx};
+ auto voice_drop_param{rp.Pop<f32>()};
+
+ auto& system_ = impl->GetSystem();
+ system_.SetVoiceDropParameter(voice_drop_param);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+ }
+
+ void GetVoiceDropParameter(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_Audio, "called");
+
+ auto& system_ = impl->GetSystem();
+ auto voice_drop_param{system_.GetVoiceDropParameter()};
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(voice_drop_param);
+ }
+
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* rendered_event;
Manager& manager;
@@ -239,7 +265,7 @@ public:
};
RegisterHandlers(functions);
- event->GetWritableEvent().Signal();
+ event->Signal();
}
~IAudioDevice() override {
@@ -325,7 +351,7 @@ private:
void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_Audio, "(STUBBED) called");
- event->GetWritableEvent().Signal();
+ event->Signal();
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp
index cd0b405ff..847f76987 100644
--- a/src/core/hle/service/bcat/backend/backend.cpp
+++ b/src/core/hle/service/bcat/backend/backend.cpp
@@ -82,7 +82,7 @@ void ProgressServiceBackend::FinishDownload(Result result) {
}
void ProgressServiceBackend::SignalUpdate() {
- update_event->GetWritableEvent().Signal();
+ update_event->Signal();
}
Backend::Backend(DirectoryGetter getter) : dir_getter(std::move(getter)) {}
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index e23eae36a..c08274ef9 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -707,7 +707,7 @@ FSP_SRV::FSP_SRV(Core::System& system_)
{31, nullptr, "OpenGameCardFileSystem"},
{32, nullptr, "ExtendSaveDataFileSystem"},
{33, nullptr, "DeleteCacheStorage"},
- {34, nullptr, "GetCacheStorageSize"},
+ {34, &FSP_SRV::GetCacheStorageSize, "GetCacheStorageSize"},
{35, nullptr, "CreateSaveDataFileSystemByHashSalt"},
{36, nullptr, "OpenHostFileSystemWithOption"},
{51, &FSP_SRV::OpenSaveDataFileSystem, "OpenSaveDataFileSystem"},
@@ -1107,6 +1107,18 @@ void FSP_SRV::GetProgramIndexForAccessLog(Kernel::HLERequestContext& ctx) {
rb.Push(access_log_program_index);
}
+void FSP_SRV::GetCacheStorageSize(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto index{rp.Pop<s32>()};
+
+ LOG_WARNING(Service_FS, "(STUBBED) called with index={}", index);
+
+ IPC::ResponseBuilder rb{ctx, 6};
+ rb.Push(ResultSuccess);
+ rb.Push(s64{0});
+ rb.Push(s64{0});
+}
+
class IMultiCommitManager final : public ServiceFramework<IMultiCommitManager> {
public:
explicit IMultiCommitManager(Core::System& system_)
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h
index 36f552e05..3d88b97f9 100644
--- a/src/core/hle/service/filesystem/fsp_srv.h
+++ b/src/core/hle/service/filesystem/fsp_srv.h
@@ -54,6 +54,7 @@ private:
void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);
void GetProgramIndexForAccessLog(Kernel::HLERequestContext& ctx);
void OpenMultiCommitManager(Kernel::HLERequestContext& ctx);
+ void GetCacheStorageSize(Kernel::HLERequestContext& ctx);
FileSystemController& fsc;
const FileSys::ContentProvider& content_provider;
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index e0db787fc..fad532115 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -26,7 +26,7 @@ public:
{10101, &IFriendService::GetFriendList, "GetFriendList"},
{10102, nullptr, "UpdateFriendInfo"},
{10110, nullptr, "GetFriendProfileImage"},
- {10120, nullptr, "IsFriendListCacheAvailable"},
+ {10120, &IFriendService::CheckFriendListAvailability, "CheckFriendListAvailability"},
{10121, nullptr, "EnsureFriendListAvailable"},
{10200, nullptr, "SendFriendRequestForApplication"},
{10211, nullptr, "AddFacedFriendRequestForApplication"},
@@ -194,6 +194,17 @@ private:
// TODO(ogniK): Return a buffer of u64s which are the "NetworkServiceAccountId"
}
+ void CheckFriendListAvailability(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto uuid{rp.PopRaw<Common::UUID>()};
+
+ LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString());
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(true);
+ }
+
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* completion_event;
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index cb29004e8..2f871de31 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -16,7 +16,6 @@
#include "core/hid/hid_core.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_readable_event.h"
-#include "core/hle/kernel/k_writable_event.h"
#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/errors.h"
#include "core/hle/service/kernel_helpers.h"
@@ -167,7 +166,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
const auto& battery_level = controller.device->GetBattery();
auto* shared_memory = controller.shared_memory;
if (controller_type == Core::HID::NpadStyleIndex::None) {
- controller.styleset_changed_event->GetWritableEvent().Signal();
+ controller.styleset_changed_event->Signal();
return;
}
@@ -660,7 +659,6 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
ASSERT(false);
break;
case Core::HID::NpadStyleIndex::ProController:
- case Core::HID::NpadStyleIndex::Pokeball:
set_motion_state(sixaxis_fullkey_state, motion_state[0]);
break;
case Core::HID::NpadStyleIndex::Handheld:
@@ -676,6 +674,11 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
case Core::HID::NpadStyleIndex::JoyconRight:
set_motion_state(sixaxis_right_lifo_state, motion_state[1]);
break;
+ case Core::HID::NpadStyleIndex::Pokeball:
+ using namespace std::literals::chrono_literals;
+ set_motion_state(sixaxis_fullkey_state, motion_state[0]);
+ sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count();
+ break;
default:
break;
}
@@ -742,8 +745,9 @@ void Controller_NPad::SetSupportedNpadIdTypes(u8* data, std::size_t length) {
}
void Controller_NPad::GetSupportedNpadIdTypes(u32* data, std::size_t max_length) {
- ASSERT(max_length < supported_npad_id_types.size());
- std::memcpy(data, supported_npad_id_types.data(), supported_npad_id_types.size());
+ const auto copy_amount = supported_npad_id_types.size() * sizeof(u32);
+ ASSERT(max_length <= copy_amount);
+ std::memcpy(data, supported_npad_id_types.data(), copy_amount);
}
std::size_t Controller_NPad::GetSupportedNpadIdTypesSize() const {
@@ -864,7 +868,7 @@ bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
return false;
}
- if (!controller.device->IsVibrationEnabled()) {
+ if (!controller.device->IsVibrationEnabled(device_index)) {
if (controller.vibration[device_index].latest_vibration_value.low_amplitude != 0.0f ||
controller.vibration[device_index].latest_vibration_value.high_amplitude != 0.0f) {
// Send an empty vibration to stop any vibrations.
@@ -997,7 +1001,7 @@ void Controller_NPad::InitializeVibrationDeviceAtIndex(Core::HID::NpadIdType npa
}
controller.vibration[device_index].device_mounted =
- controller.device->TestVibration(device_index);
+ controller.device->IsVibrationEnabled(device_index);
}
void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) {
@@ -1029,7 +1033,7 @@ Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(Core::HID::Npad
void Controller_NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const {
const auto& controller = GetControllerFromNpadIdType(npad_id);
- controller.styleset_changed_event->GetWritableEvent().Signal();
+ controller.styleset_changed_event->Signal();
}
void Controller_NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller,
@@ -1498,25 +1502,25 @@ bool Controller_NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller
Core::HID::NpadStyleTag style = GetSupportedStyleSet();
switch (controller) {
case Core::HID::NpadStyleIndex::ProController:
- return style.fullkey;
+ return style.fullkey.As<bool>();
case Core::HID::NpadStyleIndex::JoyconDual:
- return style.joycon_dual;
+ return style.joycon_dual.As<bool>();
case Core::HID::NpadStyleIndex::JoyconLeft:
- return style.joycon_left;
+ return style.joycon_left.As<bool>();
case Core::HID::NpadStyleIndex::JoyconRight:
- return style.joycon_right;
+ return style.joycon_right.As<bool>();
case Core::HID::NpadStyleIndex::GameCube:
- return style.gamecube;
+ return style.gamecube.As<bool>();
case Core::HID::NpadStyleIndex::Pokeball:
- return style.palma;
+ return style.palma.As<bool>();
case Core::HID::NpadStyleIndex::NES:
- return style.lark;
+ return style.lark.As<bool>();
case Core::HID::NpadStyleIndex::SNES:
- return style.lucia;
+ return style.lucia.As<bool>();
case Core::HID::NpadStyleIndex::N64:
- return style.lagoon;
+ return style.lagoon.As<bool>();
case Core::HID::NpadStyleIndex::SegaGenesis:
- return style.lager;
+ return style.lager.As<bool>();
default:
return false;
}
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp
new file mode 100644
index 000000000..4564ea1e2
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/palma.cpp
@@ -0,0 +1,229 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/core_timing.h"
+#include "core/hid/emulated_controller.h"
+#include "core/hid/hid_core.h"
+#include "core/hid/hid_types.h"
+#include "core/hle/kernel/k_event.h"
+#include "core/hle/kernel/k_readable_event.h"
+#include "core/hle/service/hid/controllers/palma.h"
+#include "core/hle/service/kernel_helpers.h"
+
+namespace Service::HID {
+
+Controller_Palma::Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
+ KernelHelpers::ServiceContext& service_context_)
+ : ControllerBase{hid_core_}, service_context{service_context_} {
+ controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
+ operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent");
+}
+
+Controller_Palma::~Controller_Palma() = default;
+
+void Controller_Palma::OnInit() {}
+
+void Controller_Palma::OnRelease() {}
+
+void Controller_Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ if (!IsControllerActivated()) {
+ return;
+ }
+}
+
+Result Controller_Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id,
+ PalmaConnectionHandle& handle) {
+ active_handle.npad_id = npad_id;
+ handle = active_handle;
+ return ResultSuccess;
+}
+
+Result Controller_Palma::InitializePalma(const PalmaConnectionHandle& handle) {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ ActivateController();
+ return ResultSuccess;
+}
+
+Kernel::KReadableEvent& Controller_Palma::AcquirePalmaOperationCompleteEvent(
+ const PalmaConnectionHandle& handle) const {
+ if (handle.npad_id != active_handle.npad_id) {
+ LOG_ERROR(Service_HID, "Invalid npad id {}", handle.npad_id);
+ }
+ return operation_complete_event->GetReadableEvent();
+}
+
+Result Controller_Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
+ PalmaOperationType& operation_type,
+ PalmaOperationData& data) const {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ operation_type = operation.operation;
+ data = operation.data;
+ return ResultSuccess;
+}
+
+Result Controller_Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle,
+ u64 palma_activity) {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ operation.operation = PalmaOperationType::PlayActivity;
+ operation.result = PalmaResultSuccess;
+ operation.data = {};
+ operation_complete_event->Signal();
+ return ResultSuccess;
+}
+
+Result Controller_Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle,
+ PalmaFrModeType fr_mode_) {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ fr_mode = fr_mode_;
+ return ResultSuccess;
+}
+
+Result Controller_Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ operation.operation = PalmaOperationType::ReadStep;
+ operation.result = PalmaResultSuccess;
+ operation.data = {};
+ operation_complete_event->Signal();
+ return ResultSuccess;
+}
+
+Result Controller_Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ return ResultSuccess;
+}
+
+Result Controller_Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ return ResultSuccess;
+}
+
+void Controller_Palma::ReadPalmaApplicationSection() {}
+
+void Controller_Palma::WritePalmaApplicationSection() {}
+
+Result Controller_Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ operation.operation = PalmaOperationType::ReadUniqueCode;
+ operation.result = PalmaResultSuccess;
+ operation.data = {};
+ operation_complete_event->Signal();
+ return ResultSuccess;
+}
+
+Result Controller_Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ operation.operation = PalmaOperationType::SetUniqueCodeInvalid;
+ operation.result = PalmaResultSuccess;
+ operation.data = {};
+ operation_complete_event->Signal();
+ return ResultSuccess;
+}
+
+void Controller_Palma::WritePalmaActivityEntry() {}
+
+Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle,
+ u64 unknown) {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ operation.operation = PalmaOperationType::WriteRgbLedPatternEntry;
+ operation.result = PalmaResultSuccess;
+ operation.data = {};
+ operation_complete_event->Signal();
+ return ResultSuccess;
+}
+
+Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
+ u8* t_mem, u64 size) {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ operation.operation = PalmaOperationType::WriteWaveEntry;
+ operation.result = PalmaResultSuccess;
+ operation.data = {};
+ operation_complete_event->Signal();
+ return ResultSuccess;
+}
+
+Result Controller_Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
+ s32 database_id_version_) {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ database_id_version = database_id_version_;
+ operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion;
+ operation.result = PalmaResultSuccess;
+ operation.data[0] = {};
+ operation_complete_event->Signal();
+ return ResultSuccess;
+}
+
+Result Controller_Palma::GetPalmaDataBaseIdentificationVersion(
+ const PalmaConnectionHandle& handle) {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion;
+ operation.result = PalmaResultSuccess;
+ operation.data = {};
+ operation.data[0] = static_cast<u8>(database_id_version);
+ operation_complete_event->Signal();
+ return ResultSuccess;
+}
+
+void Controller_Palma::SuspendPalmaFeature() {}
+
+Result Controller_Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ return operation.result;
+}
+void Controller_Palma::ReadPalmaPlayLog() {}
+
+void Controller_Palma::ResetPalmaPlayLog() {}
+
+void Controller_Palma::SetIsPalmaAllConnectable(bool is_all_connectable) {
+ // If true controllers are able to be paired
+ is_connectable = is_all_connectable;
+}
+
+void Controller_Palma::SetIsPalmaPairedConnectable() {}
+
+Result Controller_Palma::PairPalma(const PalmaConnectionHandle& handle) {
+ if (handle.npad_id != active_handle.npad_id) {
+ return InvalidPalmaHandle;
+ }
+ // TODO: Do something
+ return ResultSuccess;
+}
+
+void Controller_Palma::SetPalmaBoostMode(bool boost_mode) {}
+
+void Controller_Palma::CancelWritePalmaWaveEntry() {}
+
+void Controller_Palma::EnablePalmaBoostMode() {}
+
+void Controller_Palma::GetPalmaBluetoothAddress() {}
+
+void Controller_Palma::SetDisallowedPalmaConnection() {}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h
new file mode 100644
index 000000000..1d7fc94e1
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/palma.h
@@ -0,0 +1,163 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+#include "common/common_funcs.h"
+#include "common/common_types.h"
+#include "core/hle/service/hid/controllers/controller_base.h"
+#include "core/hle/service/hid/errors.h"
+
+namespace Kernel {
+class KEvent;
+class KReadableEvent;
+} // namespace Kernel
+
+namespace Service::KernelHelpers {
+class ServiceContext;
+}
+
+namespace Core::HID {
+class EmulatedController;
+} // namespace Core::HID
+
+namespace Service::HID {
+class Controller_Palma final : public ControllerBase {
+public:
+ using PalmaOperationData = std::array<u8, 0x140>;
+
+ // This is nn::hid::PalmaOperationType
+ enum class PalmaOperationType {
+ PlayActivity,
+ SetFrModeType,
+ ReadStep,
+ EnableStep,
+ ResetStep,
+ ReadApplicationSection,
+ WriteApplicationSection,
+ ReadUniqueCode,
+ SetUniqueCodeInvalid,
+ WriteActivityEntry,
+ WriteRgbLedPatternEntry,
+ WriteWaveEntry,
+ ReadDataBaseIdentificationVersion,
+ WriteDataBaseIdentificationVersion,
+ SuspendFeature,
+ ReadPlayLog,
+ ResetPlayLog,
+ };
+
+ // This is nn::hid::PalmaWaveSet
+ enum class PalmaWaveSet : u64 {
+ Small,
+ Medium,
+ Large,
+ };
+
+ // This is nn::hid::PalmaFrModeType
+ enum class PalmaFrModeType : u64 {
+ Off,
+ B01,
+ B02,
+ B03,
+ Downloaded,
+ };
+
+ // This is nn::hid::PalmaFeature
+ enum class PalmaFeature : u64 {
+ FrMode,
+ RumbleFeedback,
+ Step,
+ MuteSwitch,
+ };
+
+ // This is nn::hid::PalmaOperationInfo
+ struct PalmaOperationInfo {
+ PalmaOperationType operation{};
+ Result result{PalmaResultSuccess};
+ PalmaOperationData data{};
+ };
+ static_assert(sizeof(PalmaOperationInfo) == 0x148, "PalmaOperationInfo is an invalid size");
+
+ // This is nn::hid::PalmaActivityEntry
+ struct PalmaActivityEntry {
+ u32 rgb_led_pattern_index;
+ INSERT_PADDING_BYTES(2);
+ PalmaWaveSet wave_set;
+ u32 wave_index;
+ INSERT_PADDING_BYTES(12);
+ };
+ static_assert(sizeof(PalmaActivityEntry) == 0x20, "PalmaActivityEntry is an invalid size");
+
+ struct PalmaConnectionHandle {
+ Core::HID::NpadIdType npad_id;
+ INSERT_PADDING_BYTES(4); // Unknown
+ };
+ static_assert(sizeof(PalmaConnectionHandle) == 0x8,
+ "PalmaConnectionHandle has incorrect size.");
+
+ explicit Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_,
+ KernelHelpers::ServiceContext& service_context_);
+ ~Controller_Palma() override;
+
+ // Called when the controller is initialized
+ void OnInit() override;
+
+ // When the controller is released
+ void OnRelease() override;
+
+ // When the controller is requesting an update for the shared memory
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
+
+ Result GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id, PalmaConnectionHandle& handle);
+ Result InitializePalma(const PalmaConnectionHandle& handle);
+ Kernel::KReadableEvent& AcquirePalmaOperationCompleteEvent(
+ const PalmaConnectionHandle& handle) const;
+ Result GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
+ PalmaOperationType& operation_type,
+ PalmaOperationData& data) const;
+ Result PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity);
+ Result SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_);
+ Result ReadPalmaStep(const PalmaConnectionHandle& handle);
+ Result EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled);
+ Result ResetPalmaStep(const PalmaConnectionHandle& handle);
+ Result ReadPalmaUniqueCode(const PalmaConnectionHandle& handle);
+ Result SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle);
+ Result WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown);
+ Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, u8* t_mem,
+ u64 size);
+ Result SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
+ s32 database_id_version_);
+ Result GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle);
+ Result GetPalmaOperationResult(const PalmaConnectionHandle& handle) const;
+ void SetIsPalmaAllConnectable(bool is_all_connectable);
+ Result PairPalma(const PalmaConnectionHandle& handle);
+ void SetPalmaBoostMode(bool boost_mode);
+
+private:
+ void ReadPalmaApplicationSection();
+ void WritePalmaApplicationSection();
+ void WritePalmaActivityEntry();
+ void SuspendPalmaFeature();
+ void ReadPalmaPlayLog();
+ void ResetPalmaPlayLog();
+ void SetIsPalmaPairedConnectable();
+ void CancelWritePalmaWaveEntry();
+ void EnablePalmaBoostMode();
+ void GetPalmaBluetoothAddress();
+ void SetDisallowedPalmaConnection();
+
+ bool is_connectable{};
+ s32 database_id_version{};
+ PalmaOperationInfo operation{};
+ PalmaFrModeType fr_mode{};
+ PalmaConnectionHandle active_handle{};
+
+ Core::HID::EmulatedController* controller;
+
+ Kernel::KEvent* operation_complete_event;
+ KernelHelpers::ServiceContext& service_context;
+};
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h
index 4613a4e60..76208e9a4 100644
--- a/src/core/hle/service/hid/errors.h
+++ b/src/core/hle/service/hid/errors.h
@@ -7,6 +7,7 @@
namespace Service::HID {
+constexpr Result PalmaResultSuccess{ErrorModule::HID, 0};
constexpr Result NpadInvalidHandle{ErrorModule::HID, 100};
constexpr Result NpadDeviceIndexOutOfRange{ErrorModule::HID, 107};
constexpr Result VibrationInvalidStyleIndex{ErrorModule::HID, 122};
@@ -17,6 +18,7 @@ constexpr Result NpadIsDualJoycon{ErrorModule::HID, 601};
constexpr Result NpadIsSameType{ErrorModule::HID, 602};
constexpr Result InvalidNpadId{ErrorModule::HID, 709};
constexpr Result NpadNotConnected{ErrorModule::HID, 710};
+constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 3d3457160..79375bd2f 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -27,6 +27,7 @@
#include "core/hle/service/hid/controllers/keyboard.h"
#include "core/hle/service/hid/controllers/mouse.h"
#include "core/hle/service/hid/controllers/npad.h"
+#include "core/hle/service/hid/controllers/palma.h"
#include "core/hle/service/hid/controllers/stubbed.h"
#include "core/hle/service/hid/controllers/touchscreen.h"
#include "core/hle/service/hid/controllers/xpad.h"
@@ -35,7 +36,8 @@ namespace Service::HID {
// Updating period for each HID device.
// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
-constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz)
+// Correct pad_update_ns is 4ms this is overclocked to lower input lag
+constexpr auto pad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz)
constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz)
constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
@@ -60,6 +62,7 @@ IAppletResource::IAppletResource(Core::System& system_,
MakeControllerWithServiceContext<Controller_NPad>(HidController::NPad, shared_memory);
MakeController<Controller_Gesture>(HidController::Gesture, shared_memory);
MakeController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor, shared_memory);
+ MakeControllerWithServiceContext<Controller_Palma>(HidController::Palma, shared_memory);
// Homebrew doesn't try to activate some controllers, so we activate them by default
GetController<Controller_NPad>(HidController::NPad).ActivateController();
@@ -310,36 +313,36 @@ Hid::Hid(Core::System& system_)
{406, nullptr, "GetNpadLeftRightInterfaceType"},
{407, nullptr, "GetNpadOfHighestBatteryLevel"},
{408, nullptr, "GetNpadOfHighestBatteryLevelForJoyRight"},
- {500, nullptr, "GetPalmaConnectionHandle"},
- {501, nullptr, "InitializePalma"},
- {502, nullptr, "AcquirePalmaOperationCompleteEvent"},
- {503, nullptr, "GetPalmaOperationInfo"},
- {504, nullptr, "PlayPalmaActivity"},
- {505, nullptr, "SetPalmaFrModeType"},
- {506, nullptr, "ReadPalmaStep"},
- {507, nullptr, "EnablePalmaStep"},
- {508, nullptr, "ResetPalmaStep"},
- {509, nullptr, "ReadPalmaApplicationSection"},
- {510, nullptr, "WritePalmaApplicationSection"},
- {511, nullptr, "ReadPalmaUniqueCode"},
- {512, nullptr, "SetPalmaUniqueCodeInvalid"},
- {513, nullptr, "WritePalmaActivityEntry"},
- {514, nullptr, "WritePalmaRgbLedPatternEntry"},
- {515, nullptr, "WritePalmaWaveEntry"},
- {516, nullptr, "SetPalmaDataBaseIdentificationVersion"},
- {517, nullptr, "GetPalmaDataBaseIdentificationVersion"},
- {518, nullptr, "SuspendPalmaFeature"},
- {519, nullptr, "GetPalmaOperationResult"},
- {520, nullptr, "ReadPalmaPlayLog"},
- {521, nullptr, "ResetPalmaPlayLog"},
+ {500, &Hid::GetPalmaConnectionHandle, "GetPalmaConnectionHandle"},
+ {501, &Hid::InitializePalma, "InitializePalma"},
+ {502, &Hid::AcquirePalmaOperationCompleteEvent, "AcquirePalmaOperationCompleteEvent"},
+ {503, &Hid::GetPalmaOperationInfo, "GetPalmaOperationInfo"},
+ {504, &Hid::PlayPalmaActivity, "PlayPalmaActivity"},
+ {505, &Hid::SetPalmaFrModeType, "SetPalmaFrModeType"},
+ {506, &Hid::ReadPalmaStep, "ReadPalmaStep"},
+ {507, &Hid::EnablePalmaStep, "EnablePalmaStep"},
+ {508, &Hid::ResetPalmaStep, "ResetPalmaStep"},
+ {509, &Hid::ReadPalmaApplicationSection, "ReadPalmaApplicationSection"},
+ {510, &Hid::WritePalmaApplicationSection, "WritePalmaApplicationSection"},
+ {511, &Hid::ReadPalmaUniqueCode, "ReadPalmaUniqueCode"},
+ {512, &Hid::SetPalmaUniqueCodeInvalid, "SetPalmaUniqueCodeInvalid"},
+ {513, &Hid::WritePalmaActivityEntry, "WritePalmaActivityEntry"},
+ {514, &Hid::WritePalmaRgbLedPatternEntry, "WritePalmaRgbLedPatternEntry"},
+ {515, &Hid::WritePalmaWaveEntry, "WritePalmaWaveEntry"},
+ {516, &Hid::SetPalmaDataBaseIdentificationVersion, "SetPalmaDataBaseIdentificationVersion"},
+ {517, &Hid::GetPalmaDataBaseIdentificationVersion, "GetPalmaDataBaseIdentificationVersion"},
+ {518, &Hid::SuspendPalmaFeature, "SuspendPalmaFeature"},
+ {519, &Hid::GetPalmaOperationResult, "GetPalmaOperationResult"},
+ {520, &Hid::ReadPalmaPlayLog, "ReadPalmaPlayLog"},
+ {521, &Hid::ResetPalmaPlayLog, "ResetPalmaPlayLog"},
{522, &Hid::SetIsPalmaAllConnectable, "SetIsPalmaAllConnectable"},
- {523, nullptr, "SetIsPalmaPairedConnectable"},
- {524, nullptr, "PairPalma"},
+ {523, &Hid::SetIsPalmaPairedConnectable, "SetIsPalmaPairedConnectable"},
+ {524, &Hid::PairPalma, "PairPalma"},
{525, &Hid::SetPalmaBoostMode, "SetPalmaBoostMode"},
- {526, nullptr, "CancelWritePalmaWaveEntry"},
- {527, nullptr, "EnablePalmaBoostMode"},
- {528, nullptr, "GetPalmaBluetoothAddress"},
- {529, nullptr, "SetDisallowedPalmaConnection"},
+ {526, &Hid::CancelWritePalmaWaveEntry, "CancelWritePalmaWaveEntry"},
+ {527, &Hid::EnablePalmaBoostMode, "EnablePalmaBoostMode"},
+ {528, &Hid::GetPalmaBluetoothAddress, "GetPalmaBluetoothAddress"},
+ {529, &Hid::SetDisallowedPalmaConnection, "SetDisallowedPalmaConnection"},
{1000, &Hid::SetNpadCommunicationMode, "SetNpadCommunicationMode"},
{1001, &Hid::GetNpadCommunicationMode, "GetNpadCommunicationMode"},
{1002, &Hid::SetTouchScreenConfiguration, "SetTouchScreenConfiguration"},
@@ -1878,14 +1881,361 @@ void Hid::IsUsbFullKeyControllerEnabled(Kernel::HLERequestContext& ctx) {
rb.Push(false);
}
+void Hid::GetPalmaConnectionHandle(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::NpadIdType npad_id;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}",
+ parameters.npad_id, parameters.applet_resource_user_id);
+
+ Controller_Palma::PalmaConnectionHandle handle;
+ auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
+ const auto result = controller.GetPalmaConnectionHandle(parameters.npad_id, handle);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(result);
+ rb.PushRaw(handle);
+}
+
+void Hid::InitializePalma(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
+ const auto result = controller.InitializePalma(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void Hid::AcquirePalmaOperationCompleteEvent(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(controller.AcquirePalmaOperationCompleteEvent(connection_handle));
+}
+
+void Hid::GetPalmaOperationInfo(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ Controller_Palma::PalmaOperationType operation_type;
+ Controller_Palma::PalmaOperationData data;
+ auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
+ const auto result = controller.GetPalmaOperationInfo(connection_handle, operation_type, data);
+
+ if (result.IsError()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+ }
+
+ ctx.WriteBuffer(data);
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(result);
+ rb.Push(static_cast<u64>(operation_type));
+}
+
+void Hid::PlayPalmaActivity(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+ const auto palma_activity{rp.Pop<u64>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, palma_activity={}",
+ connection_handle.npad_id, palma_activity);
+
+ auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
+ const auto result = controller.PlayPalmaActivity(connection_handle, palma_activity);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void Hid::SetPalmaFrModeType(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+ const auto fr_mode{rp.PopEnum<Controller_Palma::PalmaFrModeType>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, fr_mode={}",
+ connection_handle.npad_id, fr_mode);
+
+ auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
+ const auto result = controller.SetPalmaFrModeType(connection_handle, fr_mode);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void Hid::ReadPalmaStep(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
+ const auto result = controller.ReadPalmaStep(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void Hid::EnablePalmaStep(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ bool is_enabled;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ Controller_Palma::PalmaConnectionHandle connection_handle;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, is_enabled={}",
+ parameters.connection_handle.npad_id, parameters.is_enabled);
+
+ auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
+ const auto result =
+ controller.EnablePalmaStep(parameters.connection_handle, parameters.is_enabled);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void Hid::ResetPalmaStep(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ auto& controller = GetAppletResource()->GetController<Controller_Palma>(HidController::Palma);
+ const auto result = controller.ResetPalmaStep(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void Hid::ReadPalmaApplicationSection(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::WritePalmaApplicationSection(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::ReadPalmaUniqueCode(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ applet_resource->GetController<Controller_Palma>(HidController::Palma)
+ .ReadPalmaUniqueCode(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::SetPalmaUniqueCodeInvalid(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ applet_resource->GetController<Controller_Palma>(HidController::Palma)
+ .SetPalmaUniqueCodeInvalid(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::WritePalmaActivityEntry(Kernel::HLERequestContext& ctx) {
+ LOG_CRITICAL(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::WritePalmaRgbLedPatternEntry(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+ const auto unknown{rp.Pop<u64>()};
+
+ const auto buffer = ctx.ReadBuffer();
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, unknown={}",
+ connection_handle.npad_id, unknown);
+
+ applet_resource->GetController<Controller_Palma>(HidController::Palma)
+ .WritePalmaRgbLedPatternEntry(connection_handle, unknown);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::WritePalmaWaveEntry(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+ const auto wave_set{rp.PopEnum<Controller_Palma::PalmaWaveSet>()};
+ const auto unknown{rp.Pop<u64>()};
+ const auto t_mem_size{rp.Pop<u64>()};
+ const auto t_mem_handle{ctx.GetCopyHandle(0)};
+ const auto size{rp.Pop<u64>()};
+
+ ASSERT_MSG(t_mem_size == 0x3000, "t_mem_size is not 0x3000 bytes");
+
+ auto t_mem =
+ system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(t_mem_handle);
+
+ if (t_mem.IsNull()) {
+ LOG_ERROR(Service_HID, "t_mem is a nullptr for handle=0x{:08X}", t_mem_handle);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultUnknown);
+ return;
+ }
+
+ ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size");
+
+ LOG_WARNING(Service_HID,
+ "(STUBBED) called, connection_handle={}, wave_set={}, unknown={}, "
+ "t_mem_handle=0x{:08X}, t_mem_size={}, size={}",
+ connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size);
+
+ applet_resource->GetController<Controller_Palma>(HidController::Palma)
+ .WritePalmaWaveEntry(connection_handle, wave_set,
+ system.Memory().GetPointer(t_mem->GetSourceAddress()), t_mem_size);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::SetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ s32 database_id_version;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ Controller_Palma::PalmaConnectionHandle connection_handle;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}, database_id_version={}",
+ parameters.connection_handle.npad_id, parameters.database_id_version);
+
+ applet_resource->GetController<Controller_Palma>(HidController::Palma)
+ .SetPalmaDataBaseIdentificationVersion(parameters.connection_handle,
+ parameters.database_id_version);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::GetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ applet_resource->GetController<Controller_Palma>(HidController::Palma)
+ .GetPalmaDataBaseIdentificationVersion(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::SuspendPalmaFeature(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::GetPalmaOperationResult(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ const auto result = applet_resource->GetController<Controller_Palma>(HidController::Palma)
+ .GetPalmaOperationResult(connection_handle);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void Hid::ReadPalmaPlayLog(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::ResetPalmaPlayLog(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
void Hid::SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const auto applet_resource_user_id{rp.Pop<u64>()};
- const auto is_palma_all_connectable{rp.Pop<bool>()};
+ struct Parameters {
+ bool is_palma_all_connectable;
+ INSERT_PADDING_BYTES_NOINIT(7);
+ u64 applet_resource_user_id;
+ };
+ static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
LOG_WARNING(Service_HID,
- "(STUBBED) called, applet_resource_user_id={}, is_palma_all_connectable={}",
- applet_resource_user_id, is_palma_all_connectable);
+ "(STUBBED) called, is_palma_all_connectable={},applet_resource_user_id={}",
+ parameters.is_palma_all_connectable, parameters.applet_resource_user_id);
+
+ applet_resource->GetController<Controller_Palma>(HidController::Palma)
+ .SetIsPalmaAllConnectable(parameters.is_palma_all_connectable);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::SetIsPalmaPairedConnectable(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::PairPalma(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto connection_handle{rp.PopRaw<Controller_Palma::PalmaConnectionHandle>()};
+
+ LOG_WARNING(Service_HID, "(STUBBED) called, connection_handle={}", connection_handle.npad_id);
+
+ applet_resource->GetController<Controller_Palma>(HidController::Palma)
+ .PairPalma(connection_handle);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
@@ -1897,6 +2247,37 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_HID, "(STUBBED) called, palma_boost_mode={}", palma_boost_mode);
+ applet_resource->GetController<Controller_Palma>(HidController::Palma)
+ .SetPalmaBoostMode(palma_boost_mode);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::CancelWritePalmaWaveEntry(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::EnablePalmaBoostMode(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::GetPalmaBluetoothAddress(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void Hid::SetDisallowedPalmaConnection(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_HID, "(STUBBED) called");
+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index ac4333022..340d26fdc 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -33,6 +33,7 @@ enum class HidController : std::size_t {
NPad,
Gesture,
ConsoleSixAxisSensor,
+ Palma,
MaxControllers,
};
@@ -166,8 +167,36 @@ private:
void FinalizeSevenSixAxisSensor(Kernel::HLERequestContext& ctx);
void ResetSevenSixAxisSensorTimestamp(Kernel::HLERequestContext& ctx);
void IsUsbFullKeyControllerEnabled(Kernel::HLERequestContext& ctx);
+ void GetPalmaConnectionHandle(Kernel::HLERequestContext& ctx);
+ void InitializePalma(Kernel::HLERequestContext& ctx);
+ void AcquirePalmaOperationCompleteEvent(Kernel::HLERequestContext& ctx);
+ void GetPalmaOperationInfo(Kernel::HLERequestContext& ctx);
+ void PlayPalmaActivity(Kernel::HLERequestContext& ctx);
+ void SetPalmaFrModeType(Kernel::HLERequestContext& ctx);
+ void ReadPalmaStep(Kernel::HLERequestContext& ctx);
+ void EnablePalmaStep(Kernel::HLERequestContext& ctx);
+ void ResetPalmaStep(Kernel::HLERequestContext& ctx);
+ void ReadPalmaApplicationSection(Kernel::HLERequestContext& ctx);
+ void WritePalmaApplicationSection(Kernel::HLERequestContext& ctx);
+ void ReadPalmaUniqueCode(Kernel::HLERequestContext& ctx);
+ void SetPalmaUniqueCodeInvalid(Kernel::HLERequestContext& ctx);
+ void WritePalmaActivityEntry(Kernel::HLERequestContext& ctx);
+ void WritePalmaRgbLedPatternEntry(Kernel::HLERequestContext& ctx);
+ void WritePalmaWaveEntry(Kernel::HLERequestContext& ctx);
+ void SetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx);
+ void GetPalmaDataBaseIdentificationVersion(Kernel::HLERequestContext& ctx);
+ void SuspendPalmaFeature(Kernel::HLERequestContext& ctx);
+ void GetPalmaOperationResult(Kernel::HLERequestContext& ctx);
+ void ReadPalmaPlayLog(Kernel::HLERequestContext& ctx);
+ void ResetPalmaPlayLog(Kernel::HLERequestContext& ctx);
void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
+ void SetIsPalmaPairedConnectable(Kernel::HLERequestContext& ctx);
+ void PairPalma(Kernel::HLERequestContext& ctx);
void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
+ void CancelWritePalmaWaveEntry(Kernel::HLERequestContext& ctx);
+ void EnablePalmaBoostMode(Kernel::HLERequestContext& ctx);
+ void GetPalmaBluetoothAddress(Kernel::HLERequestContext& ctx);
+ void SetDisallowedPalmaConnection(Kernel::HLERequestContext& ctx);
void SetNpadCommunicationMode(Kernel::HLERequestContext& ctx);
void GetNpadCommunicationMode(Kernel::HLERequestContext& ctx);
void SetTouchScreenConfiguration(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/hid/hidbus/ringcon.cpp b/src/core/hle/service/hid/hidbus/ringcon.cpp
index ad223d649..57f1a2a26 100644
--- a/src/core/hle/service/hid/hidbus/ringcon.cpp
+++ b/src/core/hle/service/hid/hidbus/ringcon.cpp
@@ -131,12 +131,12 @@ bool RingController::SetCommand(const std::vector<u8>& data) {
case RingConCommands::ReadRepCount:
case RingConCommands::ReadTotalPushCount:
ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes");
- send_command_async_event->GetWritableEvent().Signal();
+ send_command_async_event->Signal();
return true;
case RingConCommands::ResetRepCount:
ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes");
total_rep_count = 0;
- send_command_async_event->GetWritableEvent().Signal();
+ send_command_async_event->Signal();
return true;
case RingConCommands::SaveCalData: {
ASSERT_MSG(data.size() == 0x14, "data.size is not 0x14 bytes");
@@ -144,14 +144,14 @@ bool RingController::SetCommand(const std::vector<u8>& data) {
SaveCalData save_info{};
std::memcpy(&save_info, data.data(), sizeof(SaveCalData));
user_calibration = save_info.calibration;
- send_command_async_event->GetWritableEvent().Signal();
+ send_command_async_event->Signal();
return true;
}
default:
LOG_ERROR(Service_HID, "Command not implemented {}", command);
command = RingConCommands::Error;
// Signal a reply to avoid softlocking the game
- send_command_async_event->GetWritableEvent().Signal();
+ send_command_async_event->Signal();
return false;
}
}
diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp
index c4b44cbf9..6a3453457 100644
--- a/src/core/hle/service/hid/irs.cpp
+++ b/src/core/hle/service/hid/irs.cpp
@@ -542,7 +542,8 @@ Result IRS::IsIrCameraHandleValid(const Core::IrSensor::IrCameraHandle& camera_h
Core::IrSensor::DeviceFormat& IRS::GetIrCameraSharedMemoryDeviceEntry(
const Core::IrSensor::IrCameraHandle& camera_handle) {
- ASSERT_MSG(sizeof(StatusManager::device) > camera_handle.npad_id, "invalid npad_id");
+ const auto npad_id_max_index = static_cast<u8>(sizeof(StatusManager::device));
+ ASSERT_MSG(camera_handle.npad_id < npad_id_max_index, "invalid npad_id");
return shared_memory->device[camera_handle.npad_id];
}
diff --git a/src/core/hle/service/hid/irsensor/pointing_processor.h b/src/core/hle/service/hid/irsensor/pointing_processor.h
index cf4930794..d63423aff 100644
--- a/src/core/hle/service/hid/irsensor/pointing_processor.h
+++ b/src/core/hle/service/hid/irsensor/pointing_processor.h
@@ -37,10 +37,10 @@ private:
u8 pointing_status;
INSERT_PADDING_BYTES(3);
u32 unknown;
- float unkown_float1;
+ float unknown_float1;
float position_x;
float position_y;
- float unkown_float2;
+ float unknown_float2;
Core::IrSensor::IrsRect window_of_interest;
};
static_assert(sizeof(PointingProcessorMarkerData) == 0x20,
diff --git a/src/core/hle/service/kernel_helpers.cpp b/src/core/hle/service/kernel_helpers.cpp
index 3e317367b..af133af93 100644
--- a/src/core/hle/service/kernel_helpers.cpp
+++ b/src/core/hle/service/kernel_helpers.cpp
@@ -9,7 +9,6 @@
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/k_scoped_resource_reservation.h"
-#include "core/hle/kernel/k_writable_event.h"
#include "core/hle/service/kernel_helpers.h"
namespace Service::KernelHelpers {
@@ -46,7 +45,7 @@ Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) {
}
// Initialize the event.
- event->Initialize(std::move(name), process);
+ event->Initialize(process);
// Commit the thread reservation.
event_reservation.Commit();
@@ -59,7 +58,7 @@ Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) {
void ServiceContext::CloseEvent(Kernel::KEvent* event) {
event->GetReadableEvent().Close();
- event->GetWritableEvent().Close();
+ event->Close();
}
} // namespace Service::KernelHelpers
diff --git a/src/core/hle/service/ldn/lan_discovery.cpp b/src/core/hle/service/ldn/lan_discovery.cpp
new file mode 100644
index 000000000..8f3c04550
--- /dev/null
+++ b/src/core/hle/service/ldn/lan_discovery.cpp
@@ -0,0 +1,633 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/ldn/lan_discovery.h"
+#include "core/internal_network/network.h"
+#include "core/internal_network/network_interface.h"
+
+namespace Service::LDN {
+
+LanStation::LanStation(s8 node_id_, LANDiscovery* discovery_)
+ : node_info(nullptr), status(NodeStatus::Disconnected), node_id(node_id_),
+ discovery(discovery_) {}
+
+LanStation::~LanStation() = default;
+
+NodeStatus LanStation::GetStatus() const {
+ return status;
+}
+
+void LanStation::OnClose() {
+ LOG_INFO(Service_LDN, "OnClose {}", node_id);
+ Reset();
+ discovery->UpdateNodes();
+}
+
+void LanStation::Reset() {
+ status = NodeStatus::Disconnected;
+};
+
+void LanStation::OverrideInfo() {
+ bool connected = GetStatus() == NodeStatus::Connected;
+ node_info->node_id = node_id;
+ node_info->is_connected = connected ? 1 : 0;
+}
+
+LANDiscovery::LANDiscovery(Network::RoomNetwork& room_network_)
+ : stations({{{1, this}, {2, this}, {3, this}, {4, this}, {5, this}, {6, this}, {7, this}}}),
+ room_network{room_network_} {}
+
+LANDiscovery::~LANDiscovery() {
+ if (inited) {
+ Result rc = Finalize();
+ LOG_INFO(Service_LDN, "Finalize: {}", rc.raw);
+ }
+}
+
+void LANDiscovery::InitNetworkInfo() {
+ network_info.common.bssid = GetFakeMac();
+ network_info.common.channel = WifiChannel::Wifi24_6;
+ network_info.common.link_level = LinkLevel::Good;
+ network_info.common.network_type = PackedNetworkType::Ldn;
+ network_info.common.ssid = fake_ssid;
+
+ auto& nodes = network_info.ldn.nodes;
+ for (std::size_t i = 0; i < NodeCountMax; i++) {
+ nodes[i].node_id = static_cast<s8>(i);
+ nodes[i].is_connected = 0;
+ }
+}
+
+void LANDiscovery::InitNodeStateChange() {
+ for (auto& node_update : node_changes) {
+ node_update.state_change = NodeStateChange::None;
+ }
+ for (auto& node_state : node_last_states) {
+ node_state = 0;
+ }
+}
+
+State LANDiscovery::GetState() const {
+ return state;
+}
+
+void LANDiscovery::SetState(State new_state) {
+ state = new_state;
+}
+
+Result LANDiscovery::GetNetworkInfo(NetworkInfo& out_network) const {
+ if (state == State::AccessPointCreated || state == State::StationConnected) {
+ std::memcpy(&out_network, &network_info, sizeof(network_info));
+ return ResultSuccess;
+ }
+
+ return ResultBadState;
+}
+
+Result LANDiscovery::GetNetworkInfo(NetworkInfo& out_network,
+ std::vector<NodeLatestUpdate>& out_updates,
+ std::size_t buffer_count) {
+ if (buffer_count > NodeCountMax) {
+ return ResultInvalidBufferCount;
+ }
+
+ if (state == State::AccessPointCreated || state == State::StationConnected) {
+ std::memcpy(&out_network, &network_info, sizeof(network_info));
+ for (std::size_t i = 0; i < buffer_count; i++) {
+ out_updates[i].state_change = node_changes[i].state_change;
+ node_changes[i].state_change = NodeStateChange::None;
+ }
+ return ResultSuccess;
+ }
+
+ return ResultBadState;
+}
+
+DisconnectReason LANDiscovery::GetDisconnectReason() const {
+ return disconnect_reason;
+}
+
+Result LANDiscovery::Scan(std::vector<NetworkInfo>& networks, u16& count,
+ const ScanFilter& filter) {
+ if (!IsFlagSet(filter.flag, ScanFilterFlag::NetworkType) ||
+ filter.network_type <= NetworkType::All) {
+ if (!IsFlagSet(filter.flag, ScanFilterFlag::Ssid) && filter.ssid.length >= SsidLengthMax) {
+ return ResultBadInput;
+ }
+ }
+
+ {
+ std::scoped_lock lock{packet_mutex};
+ scan_results.clear();
+
+ SendBroadcast(Network::LDNPacketType::Scan);
+ }
+
+ LOG_INFO(Service_LDN, "Waiting for scan replies");
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+
+ std::scoped_lock lock{packet_mutex};
+ for (const auto& [key, info] : scan_results) {
+ if (count >= networks.size()) {
+ break;
+ }
+
+ if (IsFlagSet(filter.flag, ScanFilterFlag::LocalCommunicationId)) {
+ if (filter.network_id.intent_id.local_communication_id !=
+ info.network_id.intent_id.local_communication_id) {
+ continue;
+ }
+ }
+ if (IsFlagSet(filter.flag, ScanFilterFlag::SessionId)) {
+ if (filter.network_id.session_id != info.network_id.session_id) {
+ continue;
+ }
+ }
+ if (IsFlagSet(filter.flag, ScanFilterFlag::NetworkType)) {
+ if (filter.network_type != static_cast<NetworkType>(info.common.network_type)) {
+ continue;
+ }
+ }
+ if (IsFlagSet(filter.flag, ScanFilterFlag::Ssid)) {
+ if (filter.ssid != info.common.ssid) {
+ continue;
+ }
+ }
+ if (IsFlagSet(filter.flag, ScanFilterFlag::SceneId)) {
+ if (filter.network_id.intent_id.scene_id != info.network_id.intent_id.scene_id) {
+ continue;
+ }
+ }
+
+ networks[count++] = info;
+ }
+
+ return ResultSuccess;
+}
+
+Result LANDiscovery::SetAdvertiseData(std::span<const u8> data) {
+ std::scoped_lock lock{packet_mutex};
+ const std::size_t size = data.size();
+ if (size > AdvertiseDataSizeMax) {
+ return ResultAdvertiseDataTooLarge;
+ }
+
+ std::memcpy(network_info.ldn.advertise_data.data(), data.data(), size);
+ network_info.ldn.advertise_data_size = static_cast<u16>(size);
+
+ UpdateNodes();
+
+ return ResultSuccess;
+}
+
+Result LANDiscovery::OpenAccessPoint() {
+ std::scoped_lock lock{packet_mutex};
+ disconnect_reason = DisconnectReason::None;
+ if (state == State::None) {
+ return ResultBadState;
+ }
+
+ ResetStations();
+ SetState(State::AccessPointOpened);
+
+ return ResultSuccess;
+}
+
+Result LANDiscovery::CloseAccessPoint() {
+ std::scoped_lock lock{packet_mutex};
+ if (state == State::None) {
+ return ResultBadState;
+ }
+
+ if (state == State::AccessPointCreated) {
+ DestroyNetwork();
+ }
+
+ ResetStations();
+ SetState(State::Initialized);
+
+ return ResultSuccess;
+}
+
+Result LANDiscovery::OpenStation() {
+ std::scoped_lock lock{packet_mutex};
+ disconnect_reason = DisconnectReason::None;
+ if (state == State::None) {
+ return ResultBadState;
+ }
+
+ ResetStations();
+ SetState(State::StationOpened);
+
+ return ResultSuccess;
+}
+
+Result LANDiscovery::CloseStation() {
+ std::scoped_lock lock{packet_mutex};
+ if (state == State::None) {
+ return ResultBadState;
+ }
+
+ if (state == State::StationConnected) {
+ Disconnect();
+ }
+
+ ResetStations();
+ SetState(State::Initialized);
+
+ return ResultSuccess;
+}
+
+Result LANDiscovery::CreateNetwork(const SecurityConfig& security_config,
+ const UserConfig& user_config,
+ const NetworkConfig& network_config) {
+ std::scoped_lock lock{packet_mutex};
+
+ if (state != State::AccessPointOpened) {
+ return ResultBadState;
+ }
+
+ InitNetworkInfo();
+ network_info.ldn.node_count_max = network_config.node_count_max;
+ network_info.ldn.security_mode = security_config.security_mode;
+
+ if (network_config.channel == WifiChannel::Default) {
+ network_info.common.channel = WifiChannel::Wifi24_6;
+ } else {
+ network_info.common.channel = network_config.channel;
+ }
+
+ std::independent_bits_engine<std::mt19937, 64, u64> bits_engine;
+ network_info.network_id.session_id.high = bits_engine();
+ network_info.network_id.session_id.low = bits_engine();
+ network_info.network_id.intent_id = network_config.intent_id;
+
+ NodeInfo& node0 = network_info.ldn.nodes[0];
+ const Result rc2 = GetNodeInfo(node0, user_config, network_config.local_communication_version);
+ if (rc2.IsError()) {
+ return ResultAccessPointConnectionFailed;
+ }
+
+ SetState(State::AccessPointCreated);
+
+ InitNodeStateChange();
+ node0.is_connected = 1;
+ UpdateNodes();
+
+ return rc2;
+}
+
+Result LANDiscovery::DestroyNetwork() {
+ for (auto local_ip : connected_clients) {
+ SendPacket(Network::LDNPacketType::DestroyNetwork, local_ip);
+ }
+
+ ResetStations();
+
+ SetState(State::AccessPointOpened);
+ lan_event();
+
+ return ResultSuccess;
+}
+
+Result LANDiscovery::Connect(const NetworkInfo& network_info_, const UserConfig& user_config,
+ u16 local_communication_version) {
+ std::scoped_lock lock{packet_mutex};
+ if (network_info_.ldn.node_count == 0) {
+ return ResultInvalidNodeCount;
+ }
+
+ Result rc = GetNodeInfo(node_info, user_config, local_communication_version);
+ if (rc.IsError()) {
+ return ResultConnectionFailed;
+ }
+
+ Ipv4Address node_host = network_info_.ldn.nodes[0].ipv4_address;
+ std::reverse(std::begin(node_host), std::end(node_host)); // htonl
+ host_ip = node_host;
+ SendPacket(Network::LDNPacketType::Connect, node_info, *host_ip);
+
+ InitNodeStateChange();
+
+ std::this_thread::sleep_for(std::chrono::seconds(1));
+
+ return ResultSuccess;
+}
+
+Result LANDiscovery::Disconnect() {
+ if (host_ip) {
+ SendPacket(Network::LDNPacketType::Disconnect, node_info, *host_ip);
+ }
+
+ SetState(State::StationOpened);
+ lan_event();
+
+ return ResultSuccess;
+}
+
+Result LANDiscovery::Initialize(LanEventFunc lan_event_, bool listening) {
+ std::scoped_lock lock{packet_mutex};
+ if (inited) {
+ return ResultSuccess;
+ }
+
+ for (auto& station : stations) {
+ station.discovery = this;
+ station.node_info = &network_info.ldn.nodes[station.node_id];
+ station.Reset();
+ }
+
+ connected_clients.clear();
+ lan_event = lan_event_;
+
+ SetState(State::Initialized);
+
+ inited = true;
+ return ResultSuccess;
+}
+
+Result LANDiscovery::Finalize() {
+ std::scoped_lock lock{packet_mutex};
+ Result rc = ResultSuccess;
+
+ if (inited) {
+ if (state == State::AccessPointCreated) {
+ DestroyNetwork();
+ }
+ if (state == State::StationConnected) {
+ Disconnect();
+ }
+
+ ResetStations();
+ inited = false;
+ }
+
+ SetState(State::None);
+
+ return rc;
+}
+
+void LANDiscovery::ResetStations() {
+ for (auto& station : stations) {
+ station.Reset();
+ }
+ connected_clients.clear();
+}
+
+void LANDiscovery::UpdateNodes() {
+ u8 count = 0;
+ for (auto& station : stations) {
+ bool connected = station.GetStatus() == NodeStatus::Connected;
+ if (connected) {
+ count++;
+ }
+ station.OverrideInfo();
+ }
+ network_info.ldn.node_count = count + 1;
+
+ for (auto local_ip : connected_clients) {
+ SendPacket(Network::LDNPacketType::SyncNetwork, network_info, local_ip);
+ }
+
+ OnNetworkInfoChanged();
+}
+
+void LANDiscovery::OnSyncNetwork(const NetworkInfo& info) {
+ network_info = info;
+ if (state == State::StationOpened) {
+ SetState(State::StationConnected);
+ }
+ OnNetworkInfoChanged();
+}
+
+void LANDiscovery::OnDisconnectFromHost() {
+ LOG_INFO(Service_LDN, "OnDisconnectFromHost state: {}", static_cast<int>(state));
+ host_ip = std::nullopt;
+ if (state == State::StationConnected) {
+ SetState(State::StationOpened);
+ lan_event();
+ }
+}
+
+void LANDiscovery::OnNetworkInfoChanged() {
+ if (IsNodeStateChanged()) {
+ lan_event();
+ }
+ return;
+}
+
+Network::IPv4Address LANDiscovery::GetLocalIp() const {
+ Network::IPv4Address local_ip{0xFF, 0xFF, 0xFF, 0xFF};
+ if (auto room_member = room_network.GetRoomMember().lock()) {
+ if (room_member->IsConnected()) {
+ local_ip = room_member->GetFakeIpAddress();
+ }
+ }
+ return local_ip;
+}
+
+template <typename Data>
+void LANDiscovery::SendPacket(Network::LDNPacketType type, const Data& data,
+ Ipv4Address remote_ip) {
+ Network::LDNPacket packet;
+ packet.type = type;
+
+ packet.broadcast = false;
+ packet.local_ip = GetLocalIp();
+ packet.remote_ip = remote_ip;
+
+ packet.data.resize(sizeof(data));
+ std::memcpy(packet.data.data(), &data, sizeof(data));
+ SendPacket(packet);
+}
+
+void LANDiscovery::SendPacket(Network::LDNPacketType type, Ipv4Address remote_ip) {
+ Network::LDNPacket packet;
+ packet.type = type;
+
+ packet.broadcast = false;
+ packet.local_ip = GetLocalIp();
+ packet.remote_ip = remote_ip;
+
+ SendPacket(packet);
+}
+
+template <typename Data>
+void LANDiscovery::SendBroadcast(Network::LDNPacketType type, const Data& data) {
+ Network::LDNPacket packet;
+ packet.type = type;
+
+ packet.broadcast = true;
+ packet.local_ip = GetLocalIp();
+
+ packet.data.resize(sizeof(data));
+ std::memcpy(packet.data.data(), &data, sizeof(data));
+ SendPacket(packet);
+}
+
+void LANDiscovery::SendBroadcast(Network::LDNPacketType type) {
+ Network::LDNPacket packet;
+ packet.type = type;
+
+ packet.broadcast = true;
+ packet.local_ip = GetLocalIp();
+
+ SendPacket(packet);
+}
+
+void LANDiscovery::SendPacket(const Network::LDNPacket& packet) {
+ if (auto room_member = room_network.GetRoomMember().lock()) {
+ if (room_member->IsConnected()) {
+ room_member->SendLdnPacket(packet);
+ }
+ }
+}
+
+void LANDiscovery::ReceivePacket(const Network::LDNPacket& packet) {
+ std::scoped_lock lock{packet_mutex};
+ switch (packet.type) {
+ case Network::LDNPacketType::Scan: {
+ LOG_INFO(Frontend, "Scan packet received!");
+ if (state == State::AccessPointCreated) {
+ // Reply to the sender
+ SendPacket(Network::LDNPacketType::ScanResp, network_info, packet.local_ip);
+ }
+ break;
+ }
+ case Network::LDNPacketType::ScanResp: {
+ LOG_INFO(Frontend, "ScanResp packet received!");
+
+ NetworkInfo info{};
+ std::memcpy(&info, packet.data.data(), sizeof(NetworkInfo));
+ scan_results.insert({info.common.bssid, info});
+
+ break;
+ }
+ case Network::LDNPacketType::Connect: {
+ LOG_INFO(Frontend, "Connect packet received!");
+
+ NodeInfo info{};
+ std::memcpy(&info, packet.data.data(), sizeof(NodeInfo));
+
+ connected_clients.push_back(packet.local_ip);
+
+ for (LanStation& station : stations) {
+ if (station.status != NodeStatus::Connected) {
+ *station.node_info = info;
+ station.status = NodeStatus::Connected;
+ break;
+ }
+ }
+
+ UpdateNodes();
+
+ break;
+ }
+ case Network::LDNPacketType::Disconnect: {
+ LOG_INFO(Frontend, "Disconnect packet received!");
+
+ connected_clients.erase(
+ std::remove(connected_clients.begin(), connected_clients.end(), packet.local_ip),
+ connected_clients.end());
+
+ NodeInfo info{};
+ std::memcpy(&info, packet.data.data(), sizeof(NodeInfo));
+
+ for (LanStation& station : stations) {
+ if (station.status == NodeStatus::Connected &&
+ station.node_info->mac_address == info.mac_address) {
+ station.OnClose();
+ break;
+ }
+ }
+
+ break;
+ }
+ case Network::LDNPacketType::DestroyNetwork: {
+ ResetStations();
+ OnDisconnectFromHost();
+ break;
+ }
+ case Network::LDNPacketType::SyncNetwork: {
+ if (state == State::StationOpened || state == State::StationConnected) {
+ LOG_INFO(Frontend, "SyncNetwork packet received!");
+ NetworkInfo info{};
+ std::memcpy(&info, packet.data.data(), sizeof(NetworkInfo));
+
+ OnSyncNetwork(info);
+ } else {
+ LOG_INFO(Frontend, "SyncNetwork packet received but in wrong State!");
+ }
+
+ break;
+ }
+ default: {
+ LOG_INFO(Frontend, "ReceivePacket unhandled type {}", static_cast<int>(packet.type));
+ break;
+ }
+ }
+}
+
+bool LANDiscovery::IsNodeStateChanged() {
+ bool changed = false;
+ const auto& nodes = network_info.ldn.nodes;
+ for (int i = 0; i < NodeCountMax; i++) {
+ if (nodes[i].is_connected != node_last_states[i]) {
+ if (nodes[i].is_connected) {
+ node_changes[i].state_change |= NodeStateChange::Connect;
+ } else {
+ node_changes[i].state_change |= NodeStateChange::Disconnect;
+ }
+ node_last_states[i] = nodes[i].is_connected;
+ changed = true;
+ }
+ }
+ return changed;
+}
+
+bool LANDiscovery::IsFlagSet(ScanFilterFlag flag, ScanFilterFlag search_flag) const {
+ const auto flag_value = static_cast<u32>(flag);
+ const auto search_flag_value = static_cast<u32>(search_flag);
+ return (flag_value & search_flag_value) == search_flag_value;
+}
+
+int LANDiscovery::GetStationCount() const {
+ return static_cast<int>(
+ std::count_if(stations.begin(), stations.end(), [](const auto& station) {
+ return station.GetStatus() != NodeStatus::Disconnected;
+ }));
+}
+
+MacAddress LANDiscovery::GetFakeMac() const {
+ MacAddress mac{};
+ mac.raw[0] = 0x02;
+ mac.raw[1] = 0x00;
+
+ const auto ip = GetLocalIp();
+ memcpy(mac.raw.data() + 2, &ip, sizeof(ip));
+
+ return mac;
+}
+
+Result LANDiscovery::GetNodeInfo(NodeInfo& node, const UserConfig& userConfig,
+ u16 localCommunicationVersion) {
+ const auto network_interface = Network::GetSelectedNetworkInterface();
+
+ if (!network_interface) {
+ LOG_ERROR(Service_LDN, "No network interface available");
+ return ResultNoIpAddress;
+ }
+
+ node.mac_address = GetFakeMac();
+ node.is_connected = 1;
+ std::memcpy(node.user_name.data(), userConfig.user_name.data(), UserNameBytesMax + 1);
+ node.local_communication_version = localCommunicationVersion;
+
+ Ipv4Address current_address = GetLocalIp();
+ std::reverse(std::begin(current_address), std::end(current_address)); // ntohl
+ node.ipv4_address = current_address;
+
+ return ResultSuccess;
+}
+
+} // namespace Service::LDN
diff --git a/src/core/hle/service/ldn/lan_discovery.h b/src/core/hle/service/ldn/lan_discovery.h
new file mode 100644
index 000000000..3833cd764
--- /dev/null
+++ b/src/core/hle/service/ldn/lan_discovery.h
@@ -0,0 +1,134 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+#include <cstring>
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <optional>
+#include <random>
+#include <span>
+#include <thread>
+#include <unordered_map>
+
+#include "common/logging/log.h"
+#include "common/socket_types.h"
+#include "core/hle/result.h"
+#include "core/hle/service/ldn/ldn_results.h"
+#include "core/hle/service/ldn/ldn_types.h"
+#include "network/network.h"
+
+namespace Service::LDN {
+
+class LANDiscovery;
+
+class LanStation {
+public:
+ LanStation(s8 node_id_, LANDiscovery* discovery_);
+ ~LanStation();
+
+ void OnClose();
+ NodeStatus GetStatus() const;
+ void Reset();
+ void OverrideInfo();
+
+protected:
+ friend class LANDiscovery;
+ NodeInfo* node_info;
+ NodeStatus status;
+ s8 node_id;
+ LANDiscovery* discovery;
+};
+
+class LANDiscovery {
+public:
+ using LanEventFunc = std::function<void()>;
+
+ LANDiscovery(Network::RoomNetwork& room_network_);
+ ~LANDiscovery();
+
+ State GetState() const;
+ void SetState(State new_state);
+
+ Result GetNetworkInfo(NetworkInfo& out_network) const;
+ Result GetNetworkInfo(NetworkInfo& out_network, std::vector<NodeLatestUpdate>& out_updates,
+ std::size_t buffer_count);
+
+ DisconnectReason GetDisconnectReason() const;
+ Result Scan(std::vector<NetworkInfo>& networks, u16& count, const ScanFilter& filter);
+ Result SetAdvertiseData(std::span<const u8> data);
+
+ Result OpenAccessPoint();
+ Result CloseAccessPoint();
+
+ Result OpenStation();
+ Result CloseStation();
+
+ Result CreateNetwork(const SecurityConfig& security_config, const UserConfig& user_config,
+ const NetworkConfig& network_config);
+ Result DestroyNetwork();
+
+ Result Connect(const NetworkInfo& network_info_, const UserConfig& user_config,
+ u16 local_communication_version);
+ Result Disconnect();
+
+ Result Initialize(LanEventFunc lan_event_ = empty_func, bool listening = true);
+ Result Finalize();
+
+ void ReceivePacket(const Network::LDNPacket& packet);
+
+protected:
+ friend class LanStation;
+
+ void InitNetworkInfo();
+ void InitNodeStateChange();
+
+ void ResetStations();
+ void UpdateNodes();
+
+ void OnSyncNetwork(const NetworkInfo& info);
+ void OnDisconnectFromHost();
+ void OnNetworkInfoChanged();
+
+ bool IsNodeStateChanged();
+ bool IsFlagSet(ScanFilterFlag flag, ScanFilterFlag search_flag) const;
+ int GetStationCount() const;
+ MacAddress GetFakeMac() const;
+ Result GetNodeInfo(NodeInfo& node, const UserConfig& user_config,
+ u16 local_communication_version);
+
+ Network::IPv4Address GetLocalIp() const;
+ template <typename Data>
+ void SendPacket(Network::LDNPacketType type, const Data& data, Ipv4Address remote_ip);
+ void SendPacket(Network::LDNPacketType type, Ipv4Address remote_ip);
+ template <typename Data>
+ void SendBroadcast(Network::LDNPacketType type, const Data& data);
+ void SendBroadcast(Network::LDNPacketType type);
+ void SendPacket(const Network::LDNPacket& packet);
+
+ static const LanEventFunc empty_func;
+ static constexpr Ssid fake_ssid{"YuzuFakeSsidForLdn"};
+
+ bool inited{};
+ std::mutex packet_mutex;
+ std::array<LanStation, StationCountMax> stations;
+ std::array<NodeLatestUpdate, NodeCountMax> node_changes{};
+ std::array<u8, NodeCountMax> node_last_states{};
+ std::unordered_map<MacAddress, NetworkInfo, MACAddressHash> scan_results{};
+ NodeInfo node_info{};
+ NetworkInfo network_info{};
+ State state{State::None};
+ DisconnectReason disconnect_reason{DisconnectReason::None};
+
+ // TODO (flTobi): Should this be an std::set?
+ std::vector<Ipv4Address> connected_clients;
+ std::optional<Ipv4Address> host_ip;
+
+ LanEventFunc lan_event;
+
+ Network::RoomNetwork& room_network;
+};
+} // namespace Service::LDN
diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp
index c11daff54..6df563136 100644
--- a/src/core/hle/service/ldn/ldn.cpp
+++ b/src/core/hle/service/ldn/ldn.cpp
@@ -4,11 +4,13 @@
#include <memory>
#include "core/core.h"
+#include "core/hle/service/ldn/lan_discovery.h"
#include "core/hle/service/ldn/ldn.h"
#include "core/hle/service/ldn/ldn_results.h"
#include "core/hle/service/ldn/ldn_types.h"
#include "core/internal_network/network.h"
#include "core/internal_network/network_interface.h"
+#include "network/network.h"
// This is defined by synchapi.h and conflicts with ServiceContext::CreateEvent
#undef CreateEvent
@@ -105,13 +107,13 @@ class IUserLocalCommunicationService final
public:
explicit IUserLocalCommunicationService(Core::System& system_)
: ServiceFramework{system_, "IUserLocalCommunicationService", ServiceThreadType::CreateNew},
- service_context{system, "IUserLocalCommunicationService"}, room_network{
- system_.GetRoomNetwork()} {
+ service_context{system, "IUserLocalCommunicationService"},
+ room_network{system_.GetRoomNetwork()}, lan_discovery{room_network} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IUserLocalCommunicationService::GetState, "GetState"},
{1, &IUserLocalCommunicationService::GetNetworkInfo, "GetNetworkInfo"},
- {2, nullptr, "GetIpv4Address"},
+ {2, &IUserLocalCommunicationService::GetIpv4Address, "GetIpv4Address"},
{3, &IUserLocalCommunicationService::GetDisconnectReason, "GetDisconnectReason"},
{4, &IUserLocalCommunicationService::GetSecurityParameter, "GetSecurityParameter"},
{5, &IUserLocalCommunicationService::GetNetworkConfig, "GetNetworkConfig"},
@@ -119,7 +121,7 @@ public:
{101, &IUserLocalCommunicationService::GetNetworkInfoLatestUpdate, "GetNetworkInfoLatestUpdate"},
{102, &IUserLocalCommunicationService::Scan, "Scan"},
{103, &IUserLocalCommunicationService::ScanPrivate, "ScanPrivate"},
- {104, nullptr, "SetWirelessControllerRestriction"},
+ {104, &IUserLocalCommunicationService::SetWirelessControllerRestriction, "SetWirelessControllerRestriction"},
{200, &IUserLocalCommunicationService::OpenAccessPoint, "OpenAccessPoint"},
{201, &IUserLocalCommunicationService::CloseAccessPoint, "CloseAccessPoint"},
{202, &IUserLocalCommunicationService::CreateNetwork, "CreateNetwork"},
@@ -148,16 +150,30 @@ public:
}
~IUserLocalCommunicationService() {
+ if (is_initialized) {
+ if (auto room_member = room_network.GetRoomMember().lock()) {
+ room_member->Unbind(ldn_packet_received);
+ }
+ }
+
service_context.CloseEvent(state_change_event);
}
+ /// Callback to parse and handle a received LDN packet.
+ void OnLDNPacketReceived(const Network::LDNPacket& packet) {
+ lan_discovery.ReceivePacket(packet);
+ }
+
void OnEventFired() {
- state_change_event->GetWritableEvent().Signal();
+ state_change_event->Signal();
}
void GetState(Kernel::HLERequestContext& ctx) {
State state = State::Error;
- LOG_WARNING(Service_LDN, "(STUBBED) called, state = {}", state);
+
+ if (is_initialized) {
+ state = lan_discovery.GetState();
+ }
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
@@ -175,7 +191,7 @@ public:
}
NetworkInfo network_info{};
- const auto rc = ResultSuccess;
+ const auto rc = lan_discovery.GetNetworkInfo(network_info);
if (rc.IsError()) {
LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw);
IPC::ResponseBuilder rb{ctx, 2};
@@ -183,28 +199,50 @@ public:
return;
}
- LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}",
- network_info.common.ssid.GetStringValue(), network_info.ldn.node_count);
-
ctx.WriteBuffer<NetworkInfo>(network_info);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(rc);
+ rb.Push(ResultSuccess);
}
- void GetDisconnectReason(Kernel::HLERequestContext& ctx) {
- const auto disconnect_reason = DisconnectReason::None;
+ void GetIpv4Address(Kernel::HLERequestContext& ctx) {
+ const auto network_interface = Network::GetSelectedNetworkInterface();
+
+ if (!network_interface) {
+ LOG_ERROR(Service_LDN, "No network interface available");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultNoIpAddress);
+ return;
+ }
- LOG_WARNING(Service_LDN, "(STUBBED) called, disconnect_reason={}", disconnect_reason);
+ Ipv4Address current_address{Network::TranslateIPv4(network_interface->ip_address)};
+ Ipv4Address subnet_mask{Network::TranslateIPv4(network_interface->subnet_mask)};
+
+ // When we're connected to a room, spoof the hosts IP address
+ if (auto room_member = room_network.GetRoomMember().lock()) {
+ if (room_member->IsConnected()) {
+ current_address = room_member->GetFakeIpAddress();
+ }
+ }
+
+ std::reverse(std::begin(current_address), std::end(current_address)); // ntohl
+ std::reverse(std::begin(subnet_mask), std::end(subnet_mask)); // ntohl
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.PushRaw(current_address);
+ rb.PushRaw(subnet_mask);
+ }
+ void GetDisconnectReason(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
- rb.PushEnum(disconnect_reason);
+ rb.PushEnum(lan_discovery.GetDisconnectReason());
}
void GetSecurityParameter(Kernel::HLERequestContext& ctx) {
SecurityParameter security_parameter{};
NetworkInfo info{};
- const Result rc = ResultSuccess;
+ const Result rc = lan_discovery.GetNetworkInfo(info);
if (rc.IsError()) {
LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw);
@@ -217,8 +255,6 @@ public:
std::memcpy(security_parameter.data.data(), info.ldn.security_parameter.data(),
sizeof(SecurityParameter::data));
- LOG_WARNING(Service_LDN, "(STUBBED) called");
-
IPC::ResponseBuilder rb{ctx, 10};
rb.Push(rc);
rb.PushRaw<SecurityParameter>(security_parameter);
@@ -227,7 +263,7 @@ public:
void GetNetworkConfig(Kernel::HLERequestContext& ctx) {
NetworkConfig config{};
NetworkInfo info{};
- const Result rc = ResultSuccess;
+ const Result rc = lan_discovery.GetNetworkInfo(info);
if (rc.IsError()) {
LOG_ERROR(Service_LDN, "NetworkConfig is not valid {}", rc.raw);
@@ -241,12 +277,6 @@ public:
config.node_count_max = info.ldn.node_count_max;
config.local_communication_version = info.ldn.nodes[0].local_communication_version;
- LOG_WARNING(Service_LDN,
- "(STUBBED) called, intent_id={}/{}, channel={}, node_count_max={}, "
- "local_communication_version={}",
- config.intent_id.local_communication_id, config.intent_id.scene_id,
- config.channel, config.node_count_max, config.local_communication_version);
-
IPC::ResponseBuilder rb{ctx, 10};
rb.Push(rc);
rb.PushRaw<NetworkConfig>(config);
@@ -265,17 +295,17 @@ public:
const std::size_t node_buffer_count = ctx.GetWriteBufferSize(1) / sizeof(NodeLatestUpdate);
if (node_buffer_count == 0 || network_buffer_size != sizeof(NetworkInfo)) {
- LOG_ERROR(Service_LDN, "Invalid buffer size {}, {}", network_buffer_size,
+ LOG_ERROR(Service_LDN, "Invalid buffer, size = {}, count = {}", network_buffer_size,
node_buffer_count);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultBadInput);
return;
}
- NetworkInfo info;
+ NetworkInfo info{};
std::vector<NodeLatestUpdate> latest_update(node_buffer_count);
- const auto rc = ResultSuccess;
+ const auto rc = lan_discovery.GetNetworkInfo(info, latest_update, latest_update.size());
if (rc.IsError()) {
LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw);
IPC::ResponseBuilder rb{ctx, 2};
@@ -283,9 +313,6 @@ public:
return;
}
- LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}",
- info.common.ssid.GetStringValue(), info.ldn.node_count);
-
ctx.WriteBuffer(info, 0);
ctx.WriteBuffer(latest_update, 1);
@@ -317,92 +344,78 @@ public:
u16 count = 0;
std::vector<NetworkInfo> network_infos(network_info_size);
+ Result rc = lan_discovery.Scan(network_infos, count, scan_filter);
- LOG_WARNING(Service_LDN,
- "(STUBBED) called, channel={}, filter_scan_flag={}, filter_network_type={}",
- channel, scan_filter.flag, scan_filter.network_type);
+ LOG_INFO(Service_LDN,
+ "called, channel={}, filter_scan_flag={}, filter_network_type={}, is_private={}",
+ channel, scan_filter.flag, scan_filter.network_type, is_private);
ctx.WriteBuffer(network_infos);
IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
+ rb.Push(rc);
rb.Push<u32>(count);
}
- void OpenAccessPoint(Kernel::HLERequestContext& ctx) {
+ void SetWirelessControllerRestriction(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_LDN, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
+ void OpenAccessPoint(Kernel::HLERequestContext& ctx) {
+ LOG_INFO(Service_LDN, "called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(lan_discovery.OpenAccessPoint());
+ }
+
void CloseAccessPoint(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_LDN, "(STUBBED) called");
+ LOG_INFO(Service_LDN, "called");
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(lan_discovery.CloseAccessPoint());
}
void CreateNetwork(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- struct Parameters {
- SecurityConfig security_config;
- UserConfig user_config;
- INSERT_PADDING_WORDS_NOINIT(1);
- NetworkConfig network_config;
- };
- static_assert(sizeof(Parameters) == 0x98, "Parameters has incorrect size.");
+ LOG_INFO(Service_LDN, "called");
- const auto parameters{rp.PopRaw<Parameters>()};
+ CreateNetworkImpl(ctx);
+ }
- LOG_WARNING(Service_LDN,
- "(STUBBED) called, passphrase_size={}, security_mode={}, "
- "local_communication_version={}",
- parameters.security_config.passphrase_size,
- parameters.security_config.security_mode,
- parameters.network_config.local_communication_version);
+ void CreateNetworkPrivate(Kernel::HLERequestContext& ctx) {
+ LOG_INFO(Service_LDN, "called");
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ CreateNetworkImpl(ctx, true);
}
- void CreateNetworkPrivate(Kernel::HLERequestContext& ctx) {
+ void CreateNetworkImpl(Kernel::HLERequestContext& ctx, bool is_private = false) {
IPC::RequestParser rp{ctx};
- struct Parameters {
- SecurityConfig security_config;
- SecurityParameter security_parameter;
- UserConfig user_config;
- NetworkConfig network_config;
- };
- static_assert(sizeof(Parameters) == 0xB8, "Parameters has incorrect size.");
-
- const auto parameters{rp.PopRaw<Parameters>()};
- LOG_WARNING(Service_LDN,
- "(STUBBED) called, passphrase_size={}, security_mode={}, "
- "local_communication_version={}",
- parameters.security_config.passphrase_size,
- parameters.security_config.security_mode,
- parameters.network_config.local_communication_version);
+ const auto security_config{rp.PopRaw<SecurityConfig>()};
+ [[maybe_unused]] const auto security_parameter{is_private ? rp.PopRaw<SecurityParameter>()
+ : SecurityParameter{}};
+ const auto user_config{rp.PopRaw<UserConfig>()};
+ rp.Pop<u32>(); // Padding
+ const auto network_Config{rp.PopRaw<NetworkConfig>()};
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(lan_discovery.CreateNetwork(security_config, user_config, network_Config));
}
void DestroyNetwork(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_LDN, "(STUBBED) called");
+ LOG_INFO(Service_LDN, "called");
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(lan_discovery.DestroyNetwork());
}
void SetAdvertiseData(Kernel::HLERequestContext& ctx) {
std::vector<u8> read_buffer = ctx.ReadBuffer();
- LOG_WARNING(Service_LDN, "(STUBBED) called, size {}", read_buffer.size());
-
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(lan_discovery.SetAdvertiseData(read_buffer));
}
void SetStationAcceptPolicy(Kernel::HLERequestContext& ctx) {
@@ -420,17 +433,17 @@ public:
}
void OpenStation(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_LDN, "(STUBBED) called");
+ LOG_INFO(Service_LDN, "called");
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(lan_discovery.OpenStation());
}
void CloseStation(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_LDN, "(STUBBED) called");
+ LOG_INFO(Service_LDN, "called");
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(lan_discovery.CloseStation());
}
void Connect(Kernel::HLERequestContext& ctx) {
@@ -445,16 +458,13 @@ public:
const auto parameters{rp.PopRaw<Parameters>()};
- LOG_WARNING(Service_LDN,
- "(STUBBED) called, passphrase_size={}, security_mode={}, "
- "local_communication_version={}",
- parameters.security_config.passphrase_size,
- parameters.security_config.security_mode,
- parameters.local_communication_version);
+ LOG_INFO(Service_LDN,
+ "called, passphrase_size={}, security_mode={}, "
+ "local_communication_version={}",
+ parameters.security_config.passphrase_size,
+ parameters.security_config.security_mode, parameters.local_communication_version);
const std::vector<u8> read_buffer = ctx.ReadBuffer();
- NetworkInfo network_info{};
-
if (read_buffer.size() != sizeof(NetworkInfo)) {
LOG_ERROR(Frontend, "NetworkInfo doesn't match read_buffer size!");
IPC::ResponseBuilder rb{ctx, 2};
@@ -462,40 +472,47 @@ public:
return;
}
+ NetworkInfo network_info{};
std::memcpy(&network_info, read_buffer.data(), read_buffer.size());
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(lan_discovery.Connect(network_info, parameters.user_config,
+ static_cast<u16>(parameters.local_communication_version)));
}
void Disconnect(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_LDN, "(STUBBED) called");
+ LOG_INFO(Service_LDN, "called");
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(lan_discovery.Disconnect());
}
- void Initialize(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_LDN, "(STUBBED) called");
+ void Initialize(Kernel::HLERequestContext& ctx) {
const auto rc = InitializeImpl(ctx);
+ if (rc.IsError()) {
+ LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw);
+ }
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(rc);
}
void Finalize(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_LDN, "(STUBBED) called");
+ if (auto room_member = room_network.GetRoomMember().lock()) {
+ room_member->Unbind(ldn_packet_received);
+ }
is_initialized = false;
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(lan_discovery.Finalize());
}
void Initialize2(Kernel::HLERequestContext& ctx) {
- LOG_WARNING(Service_LDN, "(STUBBED) called");
-
const auto rc = InitializeImpl(ctx);
+ if (rc.IsError()) {
+ LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw);
+ }
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(rc);
@@ -508,14 +525,26 @@ public:
return ResultAirplaneModeEnabled;
}
+ if (auto room_member = room_network.GetRoomMember().lock()) {
+ ldn_packet_received = room_member->BindOnLdnPacketReceived(
+ [this](const Network::LDNPacket& packet) { OnLDNPacketReceived(packet); });
+ } else {
+ LOG_ERROR(Service_LDN, "Couldn't bind callback!");
+ return ResultAirplaneModeEnabled;
+ }
+
+ lan_discovery.Initialize([&]() { OnEventFired(); });
is_initialized = true;
- // TODO (flTobi): Change this to ResultSuccess when LDN is fully implemented
- return ResultAirplaneModeEnabled;
+ return ResultSuccess;
}
KernelHelpers::ServiceContext service_context;
Kernel::KEvent* state_change_event;
Network::RoomNetwork& room_network;
+ LANDiscovery lan_discovery;
+
+ // Callback identifier for the OnLDNPacketReceived event.
+ Network::RoomMember::CallbackHandle<Network::LDNPacket> ldn_packet_received;
bool is_initialized{};
};
diff --git a/src/core/hle/service/ldn/ldn_types.h b/src/core/hle/service/ldn/ldn_types.h
index 6231e936d..44c2c773b 100644
--- a/src/core/hle/service/ldn/ldn_types.h
+++ b/src/core/hle/service/ldn/ldn_types.h
@@ -31,6 +31,8 @@ enum class NodeStateChange : u8 {
DisconnectAndConnect,
};
+DECLARE_ENUM_FLAG_OPERATORS(NodeStateChange)
+
enum class ScanFilterFlag : u32 {
None = 0,
LocalCommunicationId = 1 << 0,
@@ -100,13 +102,13 @@ enum class AcceptPolicy : u8 {
enum class WifiChannel : s16 {
Default = 0,
- wifi24_1 = 1,
- wifi24_6 = 6,
- wifi24_11 = 11,
- wifi50_36 = 36,
- wifi50_40 = 40,
- wifi50_44 = 44,
- wifi50_48 = 48,
+ Wifi24_1 = 1,
+ Wifi24_6 = 6,
+ Wifi24_11 = 11,
+ Wifi50_36 = 36,
+ Wifi50_40 = 40,
+ Wifi50_44 = 44,
+ Wifi50_48 = 48,
};
enum class LinkLevel : s8 {
@@ -116,6 +118,11 @@ enum class LinkLevel : s8 {
Excellent,
};
+enum class NodeStatus : u8 {
+ Disconnected,
+ Connected,
+};
+
struct NodeLatestUpdate {
NodeStateChange state_change;
INSERT_PADDING_BYTES(0x7); // Unknown
@@ -150,7 +157,7 @@ struct Ssid {
Ssid() = default;
- explicit Ssid(std::string_view data) {
+ constexpr explicit Ssid(std::string_view data) {
length = static_cast<u8>(std::min(data.size(), SsidLengthMax));
data.copy(raw.data(), length);
raw[length] = 0;
@@ -159,19 +166,18 @@ struct Ssid {
std::string GetStringValue() const {
return std::string(raw.data());
}
-};
-static_assert(sizeof(Ssid) == 0x22, "Ssid is an invalid size");
-struct Ipv4Address {
- union {
- u32 raw{};
- std::array<u8, 4> bytes;
- };
+ bool operator==(const Ssid& b) const {
+ return (length == b.length) && (std::memcmp(raw.data(), b.raw.data(), length) == 0);
+ }
- std::string GetStringValue() const {
- return fmt::format("{}.{}.{}.{}", bytes[3], bytes[2], bytes[1], bytes[0]);
+ bool operator!=(const Ssid& b) const {
+ return !operator==(b);
}
};
+static_assert(sizeof(Ssid) == 0x22, "Ssid is an invalid size");
+
+using Ipv4Address = std::array<u8, 4>;
static_assert(sizeof(Ipv4Address) == 0x4, "Ipv4Address is an invalid size");
struct MacAddress {
@@ -181,6 +187,14 @@ struct MacAddress {
};
static_assert(sizeof(MacAddress) == 0x6, "MacAddress is an invalid size");
+struct MACAddressHash {
+ size_t operator()(const MacAddress& address) const {
+ u64 value{};
+ std::memcpy(&value, address.raw.data(), sizeof(address.raw));
+ return value;
+ }
+};
+
struct ScanFilter {
NetworkId network_id;
NetworkType network_type;
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index becd6d1b9..652441bc2 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -290,7 +290,7 @@ public:
const std::size_t padding_size{page_table.GetNumGuardPages() * Kernel::PageSize};
const auto start_info{page_table.QueryInfo(start - 1)};
- if (start_info.state != Kernel::KMemoryState::Free) {
+ if (start_info.GetState() != Kernel::KMemoryState::Free) {
return {};
}
@@ -300,7 +300,7 @@ public:
const auto end_info{page_table.QueryInfo(start + size)};
- if (end_info.state != Kernel::KMemoryState::Free) {
+ if (end_info.GetState() != Kernel::KMemoryState::Free) {
return {};
}
diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp
index c484a9c8d..3a2fe938f 100644
--- a/src/core/hle/service/mii/mii_manager.cpp
+++ b/src/core/hle/service/mii/mii_manager.cpp
@@ -427,12 +427,11 @@ CharInfo MiiManager::BuildDefault(std::size_t index) {
return ConvertStoreDataToInfo(BuildDefaultStoreData(RawData::DefaultMii.at(index), user_id));
}
-CharInfo MiiManager::ConvertV3ToCharInfo(Ver3StoreData mii_v3) const {
+CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const {
Service::Mii::MiiManager manager;
auto mii = manager.BuildDefault(0);
- // Check if mii data exist
- if (mii_v3.mii_name[0] == 0) {
+ if (!ValidateV3Info(mii_v3)) {
return mii;
}
@@ -443,8 +442,15 @@ CharInfo MiiManager::ConvertV3ToCharInfo(Ver3StoreData mii_v3) const {
mii.height = mii_v3.height;
mii.build = mii_v3.build;
- memset(mii.name.data(), 0, sizeof(mii.name));
- memcpy(mii.name.data(), mii_v3.mii_name.data(), sizeof(mii_v3.mii_name));
+ // Copy name until string terminator
+ mii.name = {};
+ for (std::size_t index = 0; index < mii.name.size() - 1; index++) {
+ mii.name[index] = mii_v3.mii_name[index];
+ if (mii.name[index] == 0) {
+ break;
+ }
+ }
+
mii.font_region = mii_v3.region_information.character_set;
mii.faceline_type = mii_v3.appearance_bits1.face_shape;
@@ -504,6 +510,151 @@ CharInfo MiiManager::ConvertV3ToCharInfo(Ver3StoreData mii_v3) const {
return mii;
}
+Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const {
+ Service::Mii::MiiManager manager;
+ Ver3StoreData mii_v3{};
+
+ // TODO: We are ignoring a bunch of data from the mii_v3
+
+ mii_v3.version = 1;
+ mii_v3.mii_information.gender.Assign(mii.gender);
+ mii_v3.mii_information.favorite_color.Assign(mii.favorite_color);
+ mii_v3.height = mii.height;
+ mii_v3.build = mii.build;
+
+ // Copy name until string terminator
+ mii_v3.mii_name = {};
+ for (std::size_t index = 0; index < mii.name.size() - 1; index++) {
+ mii_v3.mii_name[index] = mii.name[index];
+ if (mii_v3.mii_name[index] == 0) {
+ break;
+ }
+ }
+
+ mii_v3.region_information.character_set.Assign(mii.font_region);
+
+ mii_v3.appearance_bits1.face_shape.Assign(mii.faceline_type);
+ mii_v3.appearance_bits1.skin_color.Assign(mii.faceline_color);
+ mii_v3.appearance_bits2.wrinkles.Assign(mii.faceline_wrinkle);
+ mii_v3.appearance_bits2.makeup.Assign(mii.faceline_make);
+
+ mii_v3.hair_style = mii.hair_type;
+ mii_v3.appearance_bits3.hair_color.Assign(mii.hair_color);
+ mii_v3.appearance_bits3.flip_hair.Assign(mii.hair_flip);
+
+ mii_v3.appearance_bits4.eye_type.Assign(mii.eye_type);
+ mii_v3.appearance_bits4.eye_color.Assign(mii.eye_color);
+ mii_v3.appearance_bits4.eye_scale.Assign(mii.eye_scale);
+ mii_v3.appearance_bits4.eye_vertical_stretch.Assign(mii.eye_aspect);
+ mii_v3.appearance_bits4.eye_rotation.Assign(mii.eye_rotate);
+ mii_v3.appearance_bits4.eye_spacing.Assign(mii.eye_x);
+ mii_v3.appearance_bits4.eye_y_position.Assign(mii.eye_y);
+
+ mii_v3.appearance_bits5.eyebrow_style.Assign(mii.eyebrow_type);
+ mii_v3.appearance_bits5.eyebrow_color.Assign(mii.eyebrow_color);
+ mii_v3.appearance_bits5.eyebrow_scale.Assign(mii.eyebrow_scale);
+ mii_v3.appearance_bits5.eyebrow_yscale.Assign(mii.eyebrow_aspect);
+ mii_v3.appearance_bits5.eyebrow_rotation.Assign(mii.eyebrow_rotate);
+ mii_v3.appearance_bits5.eyebrow_spacing.Assign(mii.eyebrow_x);
+ mii_v3.appearance_bits5.eyebrow_y_position.Assign(mii.eyebrow_y);
+
+ mii_v3.appearance_bits6.nose_type.Assign(mii.nose_type);
+ mii_v3.appearance_bits6.nose_scale.Assign(mii.nose_scale);
+ mii_v3.appearance_bits6.nose_y_position.Assign(mii.nose_y);
+
+ mii_v3.appearance_bits7.mouth_type.Assign(mii.mouth_type);
+ mii_v3.appearance_bits7.mouth_color.Assign(mii.mouth_color);
+ mii_v3.appearance_bits7.mouth_scale.Assign(mii.mouth_scale);
+ mii_v3.appearance_bits7.mouth_horizontal_stretch.Assign(mii.mouth_aspect);
+ mii_v3.appearance_bits8.mouth_y_position.Assign(mii.mouth_y);
+
+ mii_v3.appearance_bits8.mustache_type.Assign(mii.mustache_type);
+ mii_v3.appearance_bits9.mustache_scale.Assign(mii.mustache_scale);
+ mii_v3.appearance_bits9.mustache_y_position.Assign(mii.mustache_y);
+
+ mii_v3.appearance_bits9.bear_type.Assign(mii.beard_type);
+ mii_v3.appearance_bits9.facial_hair_color.Assign(mii.beard_color);
+
+ mii_v3.appearance_bits10.glasses_type.Assign(mii.glasses_type);
+ mii_v3.appearance_bits10.glasses_color.Assign(mii.glasses_color);
+ mii_v3.appearance_bits10.glasses_scale.Assign(mii.glasses_scale);
+ mii_v3.appearance_bits10.glasses_y_position.Assign(mii.glasses_y);
+
+ mii_v3.appearance_bits11.mole_enabled.Assign(mii.mole_type);
+ mii_v3.appearance_bits11.mole_scale.Assign(mii.mole_scale);
+ mii_v3.appearance_bits11.mole_x_position.Assign(mii.mole_x);
+ mii_v3.appearance_bits11.mole_y_position.Assign(mii.mole_y);
+
+ // TODO: Validate mii_v3 data
+
+ return mii_v3;
+}
+
+bool MiiManager::ValidateV3Info(const Ver3StoreData& mii_v3) const {
+ bool is_valid = mii_v3.version == 0 || mii_v3.version == 3;
+
+ is_valid = is_valid && (mii_v3.mii_name[0] != 0);
+
+ is_valid = is_valid && (mii_v3.mii_information.birth_month < 13);
+ is_valid = is_valid && (mii_v3.mii_information.birth_day < 32);
+ is_valid = is_valid && (mii_v3.mii_information.favorite_color < 12);
+ is_valid = is_valid && (mii_v3.height < 128);
+ is_valid = is_valid && (mii_v3.build < 128);
+
+ is_valid = is_valid && (mii_v3.appearance_bits1.face_shape < 12);
+ is_valid = is_valid && (mii_v3.appearance_bits1.skin_color < 7);
+ is_valid = is_valid && (mii_v3.appearance_bits2.wrinkles < 12);
+ is_valid = is_valid && (mii_v3.appearance_bits2.makeup < 12);
+
+ is_valid = is_valid && (mii_v3.hair_style < 132);
+ is_valid = is_valid && (mii_v3.appearance_bits3.hair_color < 8);
+
+ is_valid = is_valid && (mii_v3.appearance_bits4.eye_type < 60);
+ is_valid = is_valid && (mii_v3.appearance_bits4.eye_color < 6);
+ is_valid = is_valid && (mii_v3.appearance_bits4.eye_scale < 8);
+ is_valid = is_valid && (mii_v3.appearance_bits4.eye_vertical_stretch < 7);
+ is_valid = is_valid && (mii_v3.appearance_bits4.eye_rotation < 8);
+ is_valid = is_valid && (mii_v3.appearance_bits4.eye_spacing < 13);
+ is_valid = is_valid && (mii_v3.appearance_bits4.eye_y_position < 19);
+
+ is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_style < 25);
+ is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_color < 8);
+ is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_scale < 9);
+ is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_yscale < 7);
+ is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_rotation < 12);
+ is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_spacing < 12);
+ is_valid = is_valid && (mii_v3.appearance_bits5.eyebrow_y_position < 19);
+
+ is_valid = is_valid && (mii_v3.appearance_bits6.nose_type < 18);
+ is_valid = is_valid && (mii_v3.appearance_bits6.nose_scale < 9);
+ is_valid = is_valid && (mii_v3.appearance_bits6.nose_y_position < 19);
+
+ is_valid = is_valid && (mii_v3.appearance_bits7.mouth_type < 36);
+ is_valid = is_valid && (mii_v3.appearance_bits7.mouth_color < 5);
+ is_valid = is_valid && (mii_v3.appearance_bits7.mouth_scale < 9);
+ is_valid = is_valid && (mii_v3.appearance_bits7.mouth_horizontal_stretch < 7);
+ is_valid = is_valid && (mii_v3.appearance_bits8.mouth_y_position < 19);
+
+ is_valid = is_valid && (mii_v3.appearance_bits8.mustache_type < 6);
+ is_valid = is_valid && (mii_v3.appearance_bits9.mustache_scale < 7);
+ is_valid = is_valid && (mii_v3.appearance_bits9.mustache_y_position < 17);
+
+ is_valid = is_valid && (mii_v3.appearance_bits9.bear_type < 6);
+ is_valid = is_valid && (mii_v3.appearance_bits9.facial_hair_color < 8);
+
+ is_valid = is_valid && (mii_v3.appearance_bits10.glasses_type < 9);
+ is_valid = is_valid && (mii_v3.appearance_bits10.glasses_color < 6);
+ is_valid = is_valid && (mii_v3.appearance_bits10.glasses_scale < 8);
+ is_valid = is_valid && (mii_v3.appearance_bits10.glasses_y_position < 21);
+
+ is_valid = is_valid && (mii_v3.appearance_bits11.mole_enabled < 2);
+ is_valid = is_valid && (mii_v3.appearance_bits11.mole_scale < 9);
+ is_valid = is_valid && (mii_v3.appearance_bits11.mole_x_position < 17);
+ is_valid = is_valid && (mii_v3.appearance_bits11.mole_y_position < 31);
+
+ return is_valid;
+}
+
ResultVal<std::vector<MiiInfoElement>> MiiManager::GetDefault(SourceFlag source_flag) {
std::vector<MiiInfoElement> result;
diff --git a/src/core/hle/service/mii/mii_manager.h b/src/core/hle/service/mii/mii_manager.h
index d847de0bd..83ad3d343 100644
--- a/src/core/hle/service/mii/mii_manager.h
+++ b/src/core/hle/service/mii/mii_manager.h
@@ -22,7 +22,9 @@ public:
ResultVal<CharInfo> UpdateLatest(const CharInfo& info, SourceFlag source_flag);
CharInfo BuildRandom(Age age, Gender gender, Race race);
CharInfo BuildDefault(std::size_t index);
- CharInfo ConvertV3ToCharInfo(Ver3StoreData mii_v3) const;
+ CharInfo ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const;
+ Ver3StoreData ConvertCharInfoToV3(const CharInfo& mii) const;
+ bool ValidateV3Info(const Ver3StoreData& mii_v3) const;
ResultVal<std::vector<MiiInfoElement>> GetDefault(SourceFlag source_flag);
Result GetIndex(const CharInfo& info, u32& index);
diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp
index 13a843a28..046c5f18f 100644
--- a/src/core/hle/service/nfc/nfc.cpp
+++ b/src/core/hle/service/nfc/nfc.cpp
@@ -106,10 +106,10 @@ public:
{1, &IUser::FinalizeOld, "FinalizeOld"},
{2, &IUser::GetStateOld, "GetStateOld"},
{3, &IUser::IsNfcEnabledOld, "IsNfcEnabledOld"},
- {400, nullptr, "Initialize"},
- {401, nullptr, "Finalize"},
- {402, nullptr, "GetState"},
- {403, nullptr, "IsNfcEnabled"},
+ {400, &IUser::InitializeOld, "Initialize"},
+ {401, &IUser::FinalizeOld, "Finalize"},
+ {402, &IUser::GetStateOld, "GetState"},
+ {403, &IUser::IsNfcEnabledOld, "IsNfcEnabled"},
{404, nullptr, "ListDevices"},
{405, nullptr, "GetDeviceState"},
{406, nullptr, "GetNpadId"},
diff --git a/src/core/hle/service/nfp/amiibo_crypto.cpp b/src/core/hle/service/nfp/amiibo_crypto.cpp
index 31dd3a307..167e29572 100644
--- a/src/core/hle/service/nfp/amiibo_crypto.cpp
+++ b/src/core/hle/service/nfp/amiibo_crypto.cpp
@@ -9,6 +9,7 @@
#include <mbedtls/hmac_drbg.h>
#include "common/fs/file.h"
+#include "common/fs/fs.h"
#include "common/fs/path_util.h"
#include "common/logging/log.h"
#include "core/hle/service/mii/mii_manager.h"
@@ -20,14 +21,15 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) {
const auto& amiibo_data = ntag_file.user_memory;
LOG_DEBUG(Service_NFP, "uuid_lock=0x{0:x}", ntag_file.static_lock);
LOG_DEBUG(Service_NFP, "compability_container=0x{0:x}", ntag_file.compability_container);
- LOG_INFO(Service_NFP, "write_count={}", amiibo_data.write_counter);
+ LOG_DEBUG(Service_NFP, "write_count={}", static_cast<u16>(amiibo_data.write_counter));
- LOG_INFO(Service_NFP, "character_id=0x{0:x}", amiibo_data.model_info.character_id);
- LOG_INFO(Service_NFP, "character_variant={}", amiibo_data.model_info.character_variant);
- LOG_INFO(Service_NFP, "amiibo_type={}", amiibo_data.model_info.amiibo_type);
- LOG_INFO(Service_NFP, "model_number=0x{0:x}", amiibo_data.model_info.model_number);
- LOG_INFO(Service_NFP, "series={}", amiibo_data.model_info.series);
- LOG_DEBUG(Service_NFP, "fixed_value=0x{0:x}", amiibo_data.model_info.constant_value);
+ LOG_DEBUG(Service_NFP, "character_id=0x{0:x}", amiibo_data.model_info.character_id);
+ LOG_DEBUG(Service_NFP, "character_variant={}", amiibo_data.model_info.character_variant);
+ LOG_DEBUG(Service_NFP, "amiibo_type={}", amiibo_data.model_info.amiibo_type);
+ LOG_DEBUG(Service_NFP, "model_number=0x{0:x}",
+ static_cast<u16>(amiibo_data.model_info.model_number));
+ LOG_DEBUG(Service_NFP, "series={}", amiibo_data.model_info.series);
+ LOG_DEBUG(Service_NFP, "tag_type=0x{0:x}", amiibo_data.model_info.tag_type);
LOG_DEBUG(Service_NFP, "tag_dynamic_lock=0x{0:x}", ntag_file.dynamic_lock);
LOG_DEBUG(Service_NFP, "tag_CFG0=0x{0:x}", ntag_file.CFG0);
@@ -35,11 +37,12 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) {
// Validate UUID
constexpr u8 CT = 0x88; // As defined in `ISO / IEC 14443 - 3`
- if ((CT ^ ntag_file.uuid[0] ^ ntag_file.uuid[1] ^ ntag_file.uuid[2]) != ntag_file.uuid[3]) {
+ if ((CT ^ ntag_file.uuid.uid[0] ^ ntag_file.uuid.uid[1] ^ ntag_file.uuid.uid[2]) !=
+ ntag_file.uuid.uid[3]) {
return false;
}
- if ((ntag_file.uuid[4] ^ ntag_file.uuid[5] ^ ntag_file.uuid[6] ^ ntag_file.uuid[7]) !=
- ntag_file.uuid[8]) {
+ if ((ntag_file.uuid.uid[4] ^ ntag_file.uuid.uid[5] ^ ntag_file.uuid.uid[6] ^
+ ntag_file.uuid.nintendo_id) != ntag_file.uuid.lock_bytes[0]) {
return false;
}
@@ -53,11 +56,12 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) {
if (amiibo_data.constant_value != 0xA5) {
return false;
}
- if (amiibo_data.model_info.constant_value != 0x02) {
+ if (amiibo_data.model_info.tag_type != PackedTagType::Type2) {
+ return false;
+ }
+ if ((ntag_file.dynamic_lock & 0xFFFFFF) != 0x0F0001U) {
return false;
}
- // dynamic_lock value apparently is not constant
- // ntag_file.dynamic_lock == 0x0F0001
if (ntag_file.CFG0 != 0x04000000U) {
return false;
}
@@ -70,7 +74,8 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) {
NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
NTAG215File encoded_data{};
- memcpy(encoded_data.uuid2.data(), nfc_data.uuid.data() + 0x8, sizeof(encoded_data.uuid2));
+ encoded_data.uid = nfc_data.uuid.uid;
+ encoded_data.nintendo_id = nfc_data.uuid.nintendo_id;
encoded_data.static_lock = nfc_data.static_lock;
encoded_data.compability_container = nfc_data.compability_container;
encoded_data.hmac_data = nfc_data.user_memory.hmac_data;
@@ -82,10 +87,10 @@ NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
encoded_data.applicaton_write_counter = nfc_data.user_memory.applicaton_write_counter;
encoded_data.application_area_id = nfc_data.user_memory.application_area_id;
encoded_data.unknown = nfc_data.user_memory.unknown;
- encoded_data.hash = nfc_data.user_memory.hash;
+ encoded_data.unknown2 = nfc_data.user_memory.unknown2;
encoded_data.application_area = nfc_data.user_memory.application_area;
encoded_data.hmac_tag = nfc_data.user_memory.hmac_tag;
- memcpy(encoded_data.uuid.data(), nfc_data.uuid.data(), sizeof(encoded_data.uuid));
+ encoded_data.lock_bytes = nfc_data.uuid.lock_bytes;
encoded_data.model_info = nfc_data.user_memory.model_info;
encoded_data.keygen_salt = nfc_data.user_memory.keygen_salt;
encoded_data.dynamic_lock = nfc_data.dynamic_lock;
@@ -99,8 +104,9 @@ NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) {
EncryptedNTAG215File nfc_data{};
- memcpy(nfc_data.uuid.data() + 0x8, encoded_data.uuid2.data(), sizeof(encoded_data.uuid2));
- memcpy(nfc_data.uuid.data(), encoded_data.uuid.data(), sizeof(encoded_data.uuid));
+ nfc_data.uuid.uid = encoded_data.uid;
+ nfc_data.uuid.nintendo_id = encoded_data.nintendo_id;
+ nfc_data.uuid.lock_bytes = encoded_data.lock_bytes;
nfc_data.static_lock = encoded_data.static_lock;
nfc_data.compability_container = encoded_data.compability_container;
nfc_data.user_memory.hmac_data = encoded_data.hmac_data;
@@ -112,7 +118,7 @@ EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) {
nfc_data.user_memory.applicaton_write_counter = encoded_data.applicaton_write_counter;
nfc_data.user_memory.application_area_id = encoded_data.application_area_id;
nfc_data.user_memory.unknown = encoded_data.unknown;
- nfc_data.user_memory.hash = encoded_data.hash;
+ nfc_data.user_memory.unknown2 = encoded_data.unknown2;
nfc_data.user_memory.application_area = encoded_data.application_area;
nfc_data.user_memory.hmac_tag = encoded_data.hmac_tag;
nfc_data.user_memory.model_info = encoded_data.model_info;
@@ -127,10 +133,10 @@ EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) {
u32 GetTagPassword(const TagUuid& uuid) {
// Verifiy that the generated password is correct
- u32 password = 0xAA ^ (uuid[1] ^ uuid[3]);
- password &= (0x55 ^ (uuid[2] ^ uuid[4])) << 8;
- password &= (0xAA ^ (uuid[3] ^ uuid[5])) << 16;
- password &= (0x55 ^ (uuid[4] ^ uuid[6])) << 24;
+ u32 password = 0xAA ^ (uuid.uid[1] ^ uuid.uid[3]);
+ password &= (0x55 ^ (uuid.uid[2] ^ uuid.uid[4])) << 8;
+ password &= (0xAA ^ (uuid.uid[3] ^ uuid.uid[5])) << 16;
+ password &= (0x55 ^ (uuid.uid[4] ^ uuid.uid[6])) << 24;
return password;
}
@@ -138,15 +144,13 @@ HashSeed GetSeed(const NTAG215File& data) {
HashSeed seed{
.magic = data.write_counter,
.padding = {},
- .uuid1 = {},
- .uuid2 = {},
+ .uid_1 = data.uid,
+ .nintendo_id_1 = data.nintendo_id,
+ .uid_2 = data.uid,
+ .nintendo_id_2 = data.nintendo_id,
.keygen_salt = data.keygen_salt,
};
- // Copy the first 8 bytes of uuid
- memcpy(seed.uuid1.data(), data.uuid.data(), sizeof(seed.uuid1));
- memcpy(seed.uuid2.data(), data.uuid.data(), sizeof(seed.uuid2));
-
return seed;
}
@@ -165,8 +169,10 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed
output.insert(output.end(), key.magic_bytes.begin(),
key.magic_bytes.begin() + key.magic_length);
- output.insert(output.end(), seed.uuid1.begin(), seed.uuid1.end());
- output.insert(output.end(), seed.uuid2.begin(), seed.uuid2.end());
+ output.insert(output.end(), seed.uid_1.begin(), seed.uid_1.end());
+ output.emplace_back(seed.nintendo_id_1);
+ output.insert(output.end(), seed.uid_2.begin(), seed.uid_2.end());
+ output.emplace_back(seed.nintendo_id_2);
for (std::size_t i = 0; i < sizeof(seed.keygen_salt); i++) {
output.emplace_back(static_cast<u8>(seed.keygen_salt[i] ^ key.xor_pad[i]));
@@ -177,7 +183,6 @@ std::vector<u8> GenerateInternalKey(const InternalKey& key, const HashSeed& seed
void CryptoInit(CryptoCtx& ctx, mbedtls_md_context_t& hmac_ctx, const HmacKey& hmac_key,
const std::vector<u8>& seed) {
-
// Initialize context
ctx.used = false;
ctx.counter = 0;
@@ -250,14 +255,15 @@ void Cipher(const DerivedKeys& keys, const NTAG215File& in_data, NTAG215File& ou
reinterpret_cast<unsigned char*>(&out_data.settings));
// Copy the rest of the data directly
- out_data.uuid2 = in_data.uuid2;
+ out_data.uid = in_data.uid;
+ out_data.nintendo_id = in_data.nintendo_id;
+ out_data.lock_bytes = in_data.lock_bytes;
out_data.static_lock = in_data.static_lock;
out_data.compability_container = in_data.compability_container;
out_data.constant_value = in_data.constant_value;
out_data.write_counter = in_data.write_counter;
- out_data.uuid = in_data.uuid;
out_data.model_info = in_data.model_info;
out_data.keygen_salt = in_data.keygen_salt;
out_data.dynamic_lock = in_data.dynamic_lock;
@@ -274,7 +280,7 @@ bool LoadKeys(InternalKey& locked_secret, InternalKey& unfixed_info) {
Common::FS::FileType::BinaryFile};
if (!keys_file.IsOpen()) {
- LOG_ERROR(Service_NFP, "No keys detected");
+ LOG_ERROR(Service_NFP, "Failed to open key file");
return false;
}
@@ -290,6 +296,11 @@ bool LoadKeys(InternalKey& locked_secret, InternalKey& unfixed_info) {
return true;
}
+bool IsKeyAvailable() {
+ const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir);
+ return Common::FS::Exists(yuzu_keys_dir / "key_retail.bin");
+}
+
bool DecodeAmiibo(const EncryptedNTAG215File& encrypted_tag_data, NTAG215File& tag_data) {
InternalKey locked_secret{};
InternalKey unfixed_info{};
@@ -309,7 +320,7 @@ bool DecodeAmiibo(const EncryptedNTAG215File& encrypted_tag_data, NTAG215File& t
// Regenerate tag HMAC. Note: order matters, data HMAC depends on tag HMAC!
constexpr std::size_t input_length = DYNAMIC_LOCK_START - UUID_START;
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), tag_keys.hmac_key.data(),
- sizeof(HmacKey), reinterpret_cast<const unsigned char*>(&tag_data.uuid),
+ sizeof(HmacKey), reinterpret_cast<const unsigned char*>(&tag_data.uid),
input_length, reinterpret_cast<unsigned char*>(&tag_data.hmac_tag));
// Regenerate data HMAC
@@ -350,7 +361,7 @@ bool EncodeAmiibo(const NTAG215File& tag_data, EncryptedNTAG215File& encrypted_t
constexpr std::size_t input_length = DYNAMIC_LOCK_START - UUID_START;
constexpr std::size_t input_length2 = HMAC_TAG_START - WRITE_COUNTER_START;
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), tag_keys.hmac_key.data(),
- sizeof(HmacKey), reinterpret_cast<const unsigned char*>(&tag_data.uuid),
+ sizeof(HmacKey), reinterpret_cast<const unsigned char*>(&tag_data.uid),
input_length, reinterpret_cast<unsigned char*>(&encoded_tag_data.hmac_tag));
// Init mbedtls HMAC context
@@ -364,7 +375,7 @@ bool EncodeAmiibo(const NTAG215File& tag_data, EncryptedNTAG215File& encrypted_t
input_length2); // Data
mbedtls_md_hmac_update(&ctx, reinterpret_cast<unsigned char*>(&encoded_tag_data.hmac_tag),
sizeof(HashData)); // Tag HMAC
- mbedtls_md_hmac_update(&ctx, reinterpret_cast<const unsigned char*>(&tag_data.uuid),
+ mbedtls_md_hmac_update(&ctx, reinterpret_cast<const unsigned char*>(&tag_data.uid),
input_length);
mbedtls_md_hmac_finish(&ctx, reinterpret_cast<unsigned char*>(&encoded_tag_data.hmac_data));
diff --git a/src/core/hle/service/nfp/amiibo_crypto.h b/src/core/hle/service/nfp/amiibo_crypto.h
index af7335912..1fa61174e 100644
--- a/src/core/hle/service/nfp/amiibo_crypto.h
+++ b/src/core/hle/service/nfp/amiibo_crypto.h
@@ -5,7 +5,7 @@
#include <array>
-#include "core/hle/service/nfp/amiibo_types.h"
+#include "core/hle/service/nfp/nfp_types.h"
struct mbedtls_md_context_t;
@@ -22,10 +22,12 @@ using HmacKey = std::array<u8, 0x10>;
using DrgbOutput = std::array<u8, 0x20>;
struct HashSeed {
- u16 magic;
+ u16_be magic;
std::array<u8, 0xE> padding;
- std::array<u8, 0x8> uuid1;
- std::array<u8, 0x8> uuid2;
+ UniqueSerialNumber uid_1;
+ u8 nintendo_id_1;
+ UniqueSerialNumber uid_2;
+ u8 nintendo_id_2;
std::array<u8, 0x20> keygen_salt;
};
static_assert(sizeof(HashSeed) == 0x40, "HashSeed is an invalid size");
@@ -89,6 +91,9 @@ void Cipher(const DerivedKeys& keys, const NTAG215File& in_data, NTAG215File& ou
/// Loads both amiibo keys from key_retail.bin
bool LoadKeys(InternalKey& locked_secret, InternalKey& unfixed_info);
+/// Returns true if key_retail.bin exist
+bool IsKeyAvailable();
+
/// Decodes encripted amiibo data returns true if output is valid
bool DecodeAmiibo(const EncryptedNTAG215File& encrypted_tag_data, NTAG215File& tag_data);
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index e0ed3f771..0cb55ca49 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -1,1098 +1,43 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-#include <array>
-#include <atomic>
-
-#include "common/fs/file.h"
-#include "common/fs/path_util.h"
#include "common/logging/log.h"
-#include "common/string_util.h"
-#include "core/core.h"
-#include "core/hid/emulated_controller.h"
-#include "core/hid/hid_core.h"
-#include "core/hid/hid_types.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/k_event.h"
-#include "core/hle/service/mii/mii_manager.h"
-#include "core/hle/service/nfp/amiibo_crypto.h"
#include "core/hle/service/nfp/nfp.h"
#include "core/hle/service/nfp/nfp_user.h"
namespace Service::NFP {
-namespace ErrCodes {
-constexpr Result DeviceNotFound(ErrorModule::NFP, 64);
-constexpr Result WrongDeviceState(ErrorModule::NFP, 73);
-constexpr Result NfcDisabled(ErrorModule::NFP, 80);
-constexpr Result WriteAmiiboFailed(ErrorModule::NFP, 88);
-constexpr Result TagRemoved(ErrorModule::NFP, 97);
-constexpr Result ApplicationAreaIsNotInitialized(ErrorModule::NFP, 128);
-constexpr Result WrongApplicationAreaId(ErrorModule::NFP, 152);
-constexpr Result ApplicationAreaExist(ErrorModule::NFP, 168);
-} // namespace ErrCodes
-
-IUser::IUser(Module::Interface& nfp_interface_, Core::System& system_)
- : ServiceFramework{system_, "NFP::IUser"}, service_context{system_, service_name},
- nfp_interface{nfp_interface_} {
- static const FunctionInfo functions[] = {
- {0, &IUser::Initialize, "Initialize"},
- {1, &IUser::Finalize, "Finalize"},
- {2, &IUser::ListDevices, "ListDevices"},
- {3, &IUser::StartDetection, "StartDetection"},
- {4, &IUser::StopDetection, "StopDetection"},
- {5, &IUser::Mount, "Mount"},
- {6, &IUser::Unmount, "Unmount"},
- {7, &IUser::OpenApplicationArea, "OpenApplicationArea"},
- {8, &IUser::GetApplicationArea, "GetApplicationArea"},
- {9, &IUser::SetApplicationArea, "SetApplicationArea"},
- {10, &IUser::Flush, "Flush"},
- {11, nullptr, "Restore"},
- {12, &IUser::CreateApplicationArea, "CreateApplicationArea"},
- {13, &IUser::GetTagInfo, "GetTagInfo"},
- {14, &IUser::GetRegisterInfo, "GetRegisterInfo"},
- {15, &IUser::GetCommonInfo, "GetCommonInfo"},
- {16, &IUser::GetModelInfo, "GetModelInfo"},
- {17, &IUser::AttachActivateEvent, "AttachActivateEvent"},
- {18, &IUser::AttachDeactivateEvent, "AttachDeactivateEvent"},
- {19, &IUser::GetState, "GetState"},
- {20, &IUser::GetDeviceState, "GetDeviceState"},
- {21, &IUser::GetNpadId, "GetNpadId"},
- {22, &IUser::GetApplicationAreaSize, "GetApplicationAreaSize"},
- {23, &IUser::AttachAvailabilityChangeEvent, "AttachAvailabilityChangeEvent"},
- {24, &IUser::RecreateApplicationArea, "RecreateApplicationArea"},
- };
- RegisterHandlers(functions);
-
- availability_change_event = service_context.CreateEvent("IUser:AvailabilityChangeEvent");
-}
-
-void IUser::Initialize(Kernel::HLERequestContext& ctx) {
- LOG_INFO(Service_NFC, "called");
-
- state = State::Initialized;
-
- // TODO(german77): Loop through all interfaces
- nfp_interface.Initialize();
-
- IPC::ResponseBuilder rb{ctx, 2, 0};
- rb.Push(ResultSuccess);
-}
-
-void IUser::Finalize(Kernel::HLERequestContext& ctx) {
- LOG_INFO(Service_NFP, "called");
-
- state = State::NonInitialized;
-
- // TODO(german77): Loop through all interfaces
- nfp_interface.Finalize();
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
-}
-
-void IUser::ListDevices(Kernel::HLERequestContext& ctx) {
- LOG_INFO(Service_NFP, "called");
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- std::vector<u64> devices;
-
- // TODO(german77): Loop through all interfaces
- devices.push_back(nfp_interface.GetHandle());
-
- if (devices.size() == 0) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
- return;
- }
-
- ctx.WriteBuffer(devices);
-
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(static_cast<s32>(devices.size()));
-}
-
-void IUser::StartDetection(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- const auto nfp_protocol{rp.Pop<s32>()};
- LOG_INFO(Service_NFP, "called, device_handle={}, nfp_protocol={}", device_handle, nfp_protocol);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- const auto result = nfp_interface.StartDetection(nfp_protocol);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::StopDetection(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- const auto result = nfp_interface.StopDetection();
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::Mount(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- const auto model_type{rp.PopEnum<ModelType>()};
- const auto mount_target{rp.PopEnum<MountTarget>()};
- LOG_INFO(Service_NFP, "called, device_handle={}, model_type={}, mount_target={}", device_handle,
- model_type, mount_target);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- const auto result = nfp_interface.Mount();
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::Unmount(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- const auto result = nfp_interface.Unmount();
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::OpenApplicationArea(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- const auto access_id{rp.Pop<u32>()};
- LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}, access_id={}", device_handle,
- access_id);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- const auto result = nfp_interface.OpenApplicationArea(access_id);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::GetApplicationArea(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- ApplicationArea data{};
- const auto result = nfp_interface.GetApplicationArea(data);
- ctx.WriteBuffer(data);
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(result);
- rb.Push(static_cast<u32>(data.size()));
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::SetApplicationArea(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- const auto data{ctx.ReadBuffer()};
- LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}, data_size={}", device_handle,
- data.size());
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- const auto result = nfp_interface.SetApplicationArea(data);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::Flush(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}", device_handle);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- const auto result = nfp_interface.Flush();
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::CreateApplicationArea(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- const auto access_id{rp.Pop<u32>()};
- const auto data{ctx.ReadBuffer()};
- LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}, data_size={}, access_id={}",
- device_handle, access_id, data.size());
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- const auto result = nfp_interface.CreateApplicationArea(access_id, data);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::GetTagInfo(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- TagInfo tag_info{};
- const auto result = nfp_interface.GetTagInfo(tag_info);
- ctx.WriteBuffer(tag_info);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::GetRegisterInfo(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- RegisterInfo register_info{};
- const auto result = nfp_interface.GetRegisterInfo(register_info);
- ctx.WriteBuffer(register_info);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::GetCommonInfo(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- CommonInfo common_info{};
- const auto result = nfp_interface.GetCommonInfo(common_info);
- ctx.WriteBuffer(common_info);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::GetModelInfo(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- ModelInfo model_info{};
- const auto result = nfp_interface.GetModelInfo(model_info);
- ctx.WriteBuffer(model_info);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::AttachActivateEvent(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(ResultSuccess);
- rb.PushCopyObjects(nfp_interface.GetActivateEvent());
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::AttachDeactivateEvent(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(ResultSuccess);
- rb.PushCopyObjects(nfp_interface.GetDeactivateEvent());
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::GetState(Kernel::HLERequestContext& ctx) {
- LOG_DEBUG(Service_NFC, "called");
-
- IPC::ResponseBuilder rb{ctx, 3, 0};
- rb.Push(ResultSuccess);
- rb.PushEnum(state);
-}
-
-void IUser::GetDeviceState(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.PushEnum(nfp_interface.GetCurrentState());
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::GetNpadId(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.PushEnum(nfp_interface.GetNpadId());
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::GetApplicationAreaSize(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- IPC::ResponseBuilder rb{ctx, 3};
- rb.Push(ResultSuccess);
- rb.Push(sizeof(ApplicationArea));
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-void IUser::AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx) {
- LOG_DEBUG(Service_NFP, "(STUBBED) called");
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- IPC::ResponseBuilder rb{ctx, 2, 1};
- rb.Push(ResultSuccess);
- rb.PushCopyObjects(availability_change_event->GetReadableEvent());
-}
-
-void IUser::RecreateApplicationArea(Kernel::HLERequestContext& ctx) {
- IPC::RequestParser rp{ctx};
- const auto device_handle{rp.Pop<u64>()};
- const auto access_id{rp.Pop<u32>()};
- const auto data{ctx.ReadBuffer()};
- LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}, data_size={}, access_id={}",
- device_handle, access_id, data.size());
-
- if (state == State::NonInitialized) {
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::NfcDisabled);
- return;
- }
-
- // TODO(german77): Loop through all interfaces
- if (device_handle == nfp_interface.GetHandle()) {
- const auto result = nfp_interface.RecreateApplicationArea(access_id, data);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- return;
- }
-
- LOG_ERROR(Service_NFP, "Handle not found, device_handle={}", device_handle);
-
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ErrCodes::DeviceNotFound);
-}
-
-Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_,
- const char* name)
- : ServiceFramework{system_, name}, module{std::move(module_)},
- npad_id{Core::HID::NpadIdType::Player1}, service_context{system_, service_name} {
- activate_event = service_context.CreateEvent("IUser:NFPActivateEvent");
- deactivate_event = service_context.CreateEvent("IUser:NFPDeactivateEvent");
-}
-
-Module::Interface::~Interface() = default;
-
-void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) {
- LOG_DEBUG(Service_NFP, "called");
-
- IPC::ResponseBuilder rb{ctx, 2, 0, 1};
- rb.Push(ResultSuccess);
- rb.PushIpcInterface<IUser>(*this, system);
-}
-
-bool Module::Interface::LoadAmiiboFile(const std::string& filename) {
- constexpr auto tag_size_without_password = sizeof(NTAG215File) - sizeof(NTAG215Password);
- const Common::FS::IOFile amiibo_file{filename, Common::FS::FileAccessMode::Read,
- Common::FS::FileType::BinaryFile};
-
- if (!amiibo_file.IsOpen()) {
- LOG_ERROR(Service_NFP, "Amiibo is already on use");
- return false;
- }
-
- // Workaround for files with missing password data
- std::array<u8, sizeof(EncryptedNTAG215File)> buffer{};
- if (amiibo_file.Read(buffer) < tag_size_without_password) {
- LOG_ERROR(Service_NFP, "Failed to read amiibo file");
- return false;
- }
- memcpy(&encrypted_tag_data, buffer.data(), sizeof(EncryptedNTAG215File));
-
- if (!AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) {
- LOG_INFO(Service_NFP, "Invalid amiibo");
- return false;
- }
-
- file_path = filename;
- return true;
-}
-
-bool Module::Interface::LoadAmiibo(const std::string& filename) {
- if (device_state != DeviceState::SearchingForTag) {
- LOG_ERROR(Service_NFP, "Game is not looking for amiibos, current state {}", device_state);
- return false;
- }
-
- if (!LoadAmiiboFile(filename)) {
- return false;
- }
-
- device_state = DeviceState::TagFound;
- activate_event->GetWritableEvent().Signal();
- return true;
-}
-
-void Module::Interface::CloseAmiibo() {
- LOG_INFO(Service_NFP, "Remove amiibo");
- device_state = DeviceState::TagRemoved;
- is_data_decoded = false;
- is_application_area_initialized = false;
- encrypted_tag_data = {};
- tag_data = {};
- deactivate_event->GetWritableEvent().Signal();
-}
-
-Kernel::KReadableEvent& Module::Interface::GetActivateEvent() const {
- return activate_event->GetReadableEvent();
-}
-
-Kernel::KReadableEvent& Module::Interface::GetDeactivateEvent() const {
- return deactivate_event->GetReadableEvent();
-}
-
-void Module::Interface::Initialize() {
- device_state = DeviceState::Initialized;
- is_data_decoded = false;
- is_application_area_initialized = false;
- encrypted_tag_data = {};
- tag_data = {};
-}
-
-void Module::Interface::Finalize() {
- if (device_state == DeviceState::TagMounted) {
- Unmount();
- }
- if (device_state == DeviceState::SearchingForTag || device_state == DeviceState::TagRemoved) {
- StopDetection();
- }
- device_state = DeviceState::Unaviable;
-}
-
-Result Module::Interface::StartDetection(s32 protocol_) {
- auto npad_device = system.HIDCore().GetEmulatedController(npad_id);
-
- // TODO(german77): Add callback for when nfc data is available
-
- if (device_state == DeviceState::Initialized || device_state == DeviceState::TagRemoved) {
- npad_device->SetPollingMode(Common::Input::PollingMode::NFC);
- device_state = DeviceState::SearchingForTag;
- protocol = protocol_;
- return ResultSuccess;
- }
-
- LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
- return ErrCodes::WrongDeviceState;
-}
-
-Result Module::Interface::StopDetection() {
- auto npad_device = system.HIDCore().GetEmulatedController(npad_id);
- npad_device->SetPollingMode(Common::Input::PollingMode::Active);
-
- if (device_state == DeviceState::TagFound || device_state == DeviceState::TagMounted) {
- CloseAmiibo();
- return ResultSuccess;
- }
- if (device_state == DeviceState::SearchingForTag || device_state == DeviceState::TagRemoved) {
- device_state = DeviceState::Initialized;
- return ResultSuccess;
- }
-
- LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
- return ErrCodes::WrongDeviceState;
-}
-
-Result Module::Interface::Flush() {
- // Ignore write command if we can't encrypt the data
- if (!is_data_decoded) {
- return ResultSuccess;
- }
-
- constexpr auto tag_size_without_password = sizeof(NTAG215File) - sizeof(NTAG215Password);
- EncryptedNTAG215File tmp_encrypted_tag_data{};
- const Common::FS::IOFile amiibo_file{file_path, Common::FS::FileAccessMode::ReadWrite,
- Common::FS::FileType::BinaryFile};
-
- if (!amiibo_file.IsOpen()) {
- LOG_ERROR(Core, "Amiibo is already on use");
- return ErrCodes::WriteAmiiboFailed;
- }
-
- // Workaround for files with missing password data
- std::array<u8, sizeof(EncryptedNTAG215File)> buffer{};
- if (amiibo_file.Read(buffer) < tag_size_without_password) {
- LOG_ERROR(Core, "Failed to read amiibo file");
- return ErrCodes::WriteAmiiboFailed;
- }
- memcpy(&tmp_encrypted_tag_data, buffer.data(), sizeof(EncryptedNTAG215File));
-
- if (!AmiiboCrypto::IsAmiiboValid(tmp_encrypted_tag_data)) {
- LOG_INFO(Service_NFP, "Invalid amiibo");
- return ErrCodes::WriteAmiiboFailed;
- }
-
- bool is_uuid_equal = memcmp(tmp_encrypted_tag_data.uuid.data(), tag_data.uuid.data(), 8) == 0;
- bool is_character_equal = tmp_encrypted_tag_data.user_memory.model_info.character_id ==
- tag_data.model_info.character_id;
- if (!is_uuid_equal || !is_character_equal) {
- LOG_ERROR(Service_NFP, "Not the same amiibo");
- return ErrCodes::WriteAmiiboFailed;
- }
-
- if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) {
- LOG_ERROR(Service_NFP, "Failed to encode data");
- return ErrCodes::WriteAmiiboFailed;
- }
-
- // Return to the start of the file
- if (!amiibo_file.Seek(0)) {
- LOG_ERROR(Service_NFP, "Error writting to file");
- return ErrCodes::WriteAmiiboFailed;
- }
-
- if (!amiibo_file.Write(encrypted_tag_data)) {
- LOG_ERROR(Service_NFP, "Error writting to file");
- return ErrCodes::WriteAmiiboFailed;
- }
-
- return ResultSuccess;
-}
-
-Result Module::Interface::Mount() {
- if (device_state != DeviceState::TagFound) {
- LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
- return ErrCodes::WrongDeviceState;
- }
- is_data_decoded = AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data);
- LOG_INFO(Service_NFP, "Is amiibo decoded {}", is_data_decoded);
-
- is_application_area_initialized = false;
- device_state = DeviceState::TagMounted;
- return ResultSuccess;
-}
-
-Result Module::Interface::Unmount() {
- if (device_state != DeviceState::TagMounted) {
- LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
- return ErrCodes::WrongDeviceState;
- }
-
- is_data_decoded = false;
- is_application_area_initialized = false;
- device_state = DeviceState::TagFound;
- return ResultSuccess;
-}
-
-Result Module::Interface::GetTagInfo(TagInfo& tag_info) const {
- if (device_state != DeviceState::TagFound && device_state != DeviceState::TagMounted) {
- LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
- return ErrCodes::WrongDeviceState;
- }
-
- tag_info = {
- .uuid = encrypted_tag_data.uuid,
- .uuid_length = static_cast<u8>(encrypted_tag_data.uuid.size()),
- .protocol = protocol,
- .tag_type = static_cast<u32>(encrypted_tag_data.user_memory.model_info.amiibo_type),
- };
-
- return ResultSuccess;
-}
-
-Result Module::Interface::GetCommonInfo(CommonInfo& common_info) const {
- if (device_state != DeviceState::TagMounted) {
- LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
- return ErrCodes::WrongDeviceState;
- }
-
- if (is_data_decoded && tag_data.settings.settings.amiibo_initialized != 0) {
- const auto& settings = tag_data.settings;
- // TODO: Validate this data
- common_info = {
- .last_write_year = settings.write_date.GetYear(),
- .last_write_month = settings.write_date.GetMonth(),
- .last_write_day = settings.write_date.GetDay(),
- .write_counter = settings.crc_counter,
- .version = 1,
- .application_area_size = sizeof(ApplicationArea),
- };
- return ResultSuccess;
- }
-
- // Generate a generic answer
- common_info = {
- .last_write_year = 2022,
- .last_write_month = 2,
- .last_write_day = 7,
- .write_counter = 0,
- .version = 1,
- .application_area_size = sizeof(ApplicationArea),
- };
- return ResultSuccess;
-}
-
-Result Module::Interface::GetModelInfo(ModelInfo& model_info) const {
- if (device_state != DeviceState::TagMounted) {
- LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
- return ErrCodes::WrongDeviceState;
- }
-
- const auto& model_info_data = encrypted_tag_data.user_memory.model_info;
- model_info = {
- .character_id = model_info_data.character_id,
- .character_variant = model_info_data.character_variant,
- .amiibo_type = model_info_data.amiibo_type,
- .model_number = model_info_data.model_number,
- .series = model_info_data.series,
- .constant_value = model_info_data.constant_value,
- };
- return ResultSuccess;
-}
-
-Result Module::Interface::GetRegisterInfo(RegisterInfo& register_info) const {
- if (device_state != DeviceState::TagMounted) {
- LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
- if (device_state == DeviceState::TagRemoved) {
- return ErrCodes::TagRemoved;
- }
- return ErrCodes::WrongDeviceState;
- }
-
- Service::Mii::MiiManager manager;
-
- if (is_data_decoded && tag_data.settings.settings.amiibo_initialized != 0) {
- const auto& settings = tag_data.settings;
-
- // TODO: Validate this data
- register_info = {
- .mii_char_info = manager.ConvertV3ToCharInfo(tag_data.owner_mii),
- .first_write_year = settings.init_date.GetYear(),
- .first_write_month = settings.init_date.GetMonth(),
- .first_write_day = settings.init_date.GetDay(),
- .amiibo_name = GetAmiiboName(settings),
- .font_region = {},
+class IUserManager final : public ServiceFramework<IUserManager> {
+public:
+ explicit IUserManager(Core::System& system_) : ServiceFramework{system_, "nfp:user"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, &IUserManager::CreateUserInterface, "CreateUserInterface"},
};
+ // clang-format on
- return ResultSuccess;
+ RegisterHandlers(functions);
}
- // Generate a generic answer
- register_info = {
- .mii_char_info = manager.BuildDefault(0),
- .first_write_year = 2022,
- .first_write_month = 2,
- .first_write_day = 7,
- .amiibo_name = {'Y', 'u', 'z', 'u', 'A', 'm', 'i', 'i', 'b', 'o', 0},
- .font_region = {},
- };
- return ResultSuccess;
-}
+private:
+ void CreateUserInterface(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_NFP, "called");
-Result Module::Interface::OpenApplicationArea(u32 access_id) {
- if (device_state != DeviceState::TagMounted) {
- LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
- if (device_state == DeviceState::TagRemoved) {
- return ErrCodes::TagRemoved;
+ if (user_interface == nullptr) {
+ user_interface = std::make_shared<IUser>(system);
}
- return ErrCodes::WrongDeviceState;
- }
-
- // Fallback for lack of amiibo keys
- if (!is_data_decoded) {
- LOG_WARNING(Service_NFP, "Application area is not initialized");
- return ErrCodes::ApplicationAreaIsNotInitialized;
- }
- if (tag_data.settings.settings.appdata_initialized == 0) {
- LOG_WARNING(Service_NFP, "Application area is not initialized");
- return ErrCodes::ApplicationAreaIsNotInitialized;
- }
-
- if (tag_data.application_area_id != access_id) {
- LOG_WARNING(Service_NFP, "Wrong application area id");
- return ErrCodes::WrongApplicationAreaId;
- }
-
- is_application_area_initialized = true;
- return ResultSuccess;
-}
-
-Result Module::Interface::GetApplicationArea(ApplicationArea& data) const {
- if (device_state != DeviceState::TagMounted) {
- LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
- if (device_state == DeviceState::TagRemoved) {
- return ErrCodes::TagRemoved;
- }
- return ErrCodes::WrongDeviceState;
- }
-
- if (!is_application_area_initialized) {
- LOG_ERROR(Service_NFP, "Application area is not initialized");
- return ErrCodes::ApplicationAreaIsNotInitialized;
- }
-
- data = tag_data.application_area;
-
- return ResultSuccess;
-}
-
-Result Module::Interface::SetApplicationArea(const std::vector<u8>& data) {
- if (device_state != DeviceState::TagMounted) {
- LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
- if (device_state == DeviceState::TagRemoved) {
- return ErrCodes::TagRemoved;
- }
- return ErrCodes::WrongDeviceState;
- }
-
- if (!is_application_area_initialized) {
- LOG_ERROR(Service_NFP, "Application area is not initialized");
- return ErrCodes::ApplicationAreaIsNotInitialized;
- }
-
- if (data.size() != sizeof(ApplicationArea)) {
- LOG_ERROR(Service_NFP, "Wrong data size {}", data.size());
- return ResultUnknown;
- }
-
- std::memcpy(&tag_data.application_area, data.data(), sizeof(ApplicationArea));
- return ResultSuccess;
-}
-
-Result Module::Interface::CreateApplicationArea(u32 access_id, const std::vector<u8>& data) {
- if (device_state != DeviceState::TagMounted) {
- LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
- if (device_state == DeviceState::TagRemoved) {
- return ErrCodes::TagRemoved;
- }
- return ErrCodes::WrongDeviceState;
- }
-
- if (tag_data.settings.settings.appdata_initialized != 0) {
- LOG_ERROR(Service_NFP, "Application area already exist");
- return ErrCodes::ApplicationAreaExist;
- }
-
- if (data.size() != sizeof(ApplicationArea)) {
- LOG_ERROR(Service_NFP, "Wrong data size {}", data.size());
- return ResultUnknown;
- }
-
- std::memcpy(&tag_data.application_area, data.data(), sizeof(ApplicationArea));
- tag_data.application_area_id = access_id;
-
- return ResultSuccess;
-}
-
-Result Module::Interface::RecreateApplicationArea(u32 access_id, const std::vector<u8>& data) {
- if (device_state != DeviceState::TagMounted) {
- LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
- if (device_state == DeviceState::TagRemoved) {
- return ErrCodes::TagRemoved;
- }
- return ErrCodes::WrongDeviceState;
- }
-
- if (data.size() != sizeof(ApplicationArea)) {
- LOG_ERROR(Service_NFP, "Wrong data size {}", data.size());
- return ResultUnknown;
- }
-
- std::memcpy(&tag_data.application_area, data.data(), sizeof(ApplicationArea));
- tag_data.application_area_id = access_id;
-
- return ResultSuccess;
-}
-
-u64 Module::Interface::GetHandle() const {
- // Generate a handle based of the npad id
- return static_cast<u64>(npad_id);
-}
-
-DeviceState Module::Interface::GetCurrentState() const {
- return device_state;
-}
-
-Core::HID::NpadIdType Module::Interface::GetNpadId() const {
- // Return first connected npad id as a workaround for lack of a single nfc interface per
- // controller
- return system.HIDCore().GetFirstNpadId();
-}
-
-AmiiboName Module::Interface::GetAmiiboName(const AmiiboSettings& settings) const {
- std::array<char16_t, amiibo_name_length> settings_amiibo_name{};
- AmiiboName amiibo_name{};
-
- // Convert from big endian to little endian
- for (std::size_t i = 0; i < amiibo_name_length; i++) {
- settings_amiibo_name[i] = static_cast<u16>(settings.amiibo_name[i]);
+ IPC::ResponseBuilder rb{ctx, 2, 0, 1};
+ rb.Push(ResultSuccess);
+ rb.PushIpcInterface<IUser>(user_interface);
}
- // Convert from utf16 to utf8
- const auto amiibo_name_utf8 = Common::UTF16ToUTF8(settings_amiibo_name.data());
- memcpy(amiibo_name.data(), amiibo_name_utf8.data(), amiibo_name_utf8.size());
-
- return amiibo_name;
-}
+ std::shared_ptr<IUser> user_interface;
+};
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
- auto module = std::make_shared<Module>();
- std::make_shared<NFP_User>(module, system)->InstallAsService(service_manager);
+ std::make_shared<IUserManager>(system)->InstallAsService(service_manager);
}
} // namespace Service::NFP
diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h
index 0de0b48e7..a25c362b8 100644
--- a/src/core/hle/service/nfp/nfp.h
+++ b/src/core/hle/service/nfp/nfp.h
@@ -3,170 +3,9 @@
#pragma once
-#include <array>
-#include <vector>
-
-#include "common/common_funcs.h"
-#include "core/hle/service/kernel_helpers.h"
-#include "core/hle/service/mii/types.h"
-#include "core/hle/service/nfp/amiibo_types.h"
#include "core/hle/service/service.h"
-namespace Kernel {
-class KEvent;
-class KReadableEvent;
-} // namespace Kernel
-
-namespace Core::HID {
-enum class NpadIdType : u32;
-} // namespace Core::HID
-
namespace Service::NFP {
-using AmiiboName = std::array<char, (amiibo_name_length * 4) + 1>;
-
-struct TagInfo {
- TagUuid uuid;
- u8 uuid_length;
- INSERT_PADDING_BYTES(0x15);
- s32 protocol;
- u32 tag_type;
- INSERT_PADDING_BYTES(0x30);
-};
-static_assert(sizeof(TagInfo) == 0x58, "TagInfo is an invalid size");
-
-struct CommonInfo {
- u16 last_write_year;
- u8 last_write_month;
- u8 last_write_day;
- u16 write_counter;
- u16 version;
- u32 application_area_size;
- INSERT_PADDING_BYTES(0x34);
-};
-static_assert(sizeof(CommonInfo) == 0x40, "CommonInfo is an invalid size");
-
-struct ModelInfo {
- u16 character_id;
- u8 character_variant;
- AmiiboType amiibo_type;
- u16 model_number;
- AmiiboSeries series;
- u8 constant_value; // Must be 02
- INSERT_PADDING_BYTES(0x38); // Unknown
-};
-static_assert(sizeof(ModelInfo) == 0x40, "ModelInfo is an invalid size");
-
-struct RegisterInfo {
- Service::Mii::CharInfo mii_char_info;
- u16 first_write_year;
- u8 first_write_month;
- u8 first_write_day;
- AmiiboName amiibo_name;
- u8 font_region;
- INSERT_PADDING_BYTES(0x7A);
-};
-static_assert(sizeof(RegisterInfo) == 0x100, "RegisterInfo is an invalid size");
-
-class Module final {
-public:
- class Interface : public ServiceFramework<Interface> {
- public:
- explicit Interface(std::shared_ptr<Module> module_, Core::System& system_,
- const char* name);
- ~Interface() override;
-
- void CreateUserInterface(Kernel::HLERequestContext& ctx);
- bool LoadAmiibo(const std::string& filename);
- bool LoadAmiiboFile(const std::string& filename);
- void CloseAmiibo();
-
- void Initialize();
- void Finalize();
-
- Result StartDetection(s32 protocol_);
- Result StopDetection();
- Result Mount();
- Result Unmount();
- Result Flush();
-
- Result GetTagInfo(TagInfo& tag_info) const;
- Result GetCommonInfo(CommonInfo& common_info) const;
- Result GetModelInfo(ModelInfo& model_info) const;
- Result GetRegisterInfo(RegisterInfo& register_info) const;
-
- Result OpenApplicationArea(u32 access_id);
- Result GetApplicationArea(ApplicationArea& data) const;
- Result SetApplicationArea(const std::vector<u8>& data);
- Result CreateApplicationArea(u32 access_id, const std::vector<u8>& data);
- Result RecreateApplicationArea(u32 access_id, const std::vector<u8>& data);
-
- u64 GetHandle() const;
- DeviceState GetCurrentState() const;
- Core::HID::NpadIdType GetNpadId() const;
-
- Kernel::KReadableEvent& GetActivateEvent() const;
- Kernel::KReadableEvent& GetDeactivateEvent() const;
-
- protected:
- std::shared_ptr<Module> module;
-
- private:
- AmiiboName GetAmiiboName(const AmiiboSettings& settings) const;
-
- const Core::HID::NpadIdType npad_id;
-
- bool is_data_decoded{};
- bool is_application_area_initialized{};
- s32 protocol;
- std::string file_path{};
- Kernel::KEvent* activate_event;
- Kernel::KEvent* deactivate_event;
- DeviceState device_state{DeviceState::Unaviable};
- KernelHelpers::ServiceContext service_context;
-
- NTAG215File tag_data{};
- EncryptedNTAG215File encrypted_tag_data{};
- };
-};
-
-class IUser final : public ServiceFramework<IUser> {
-public:
- explicit IUser(Module::Interface& nfp_interface_, Core::System& system_);
-
-private:
- void Initialize(Kernel::HLERequestContext& ctx);
- void Finalize(Kernel::HLERequestContext& ctx);
- void ListDevices(Kernel::HLERequestContext& ctx);
- void StartDetection(Kernel::HLERequestContext& ctx);
- void StopDetection(Kernel::HLERequestContext& ctx);
- void Mount(Kernel::HLERequestContext& ctx);
- void Unmount(Kernel::HLERequestContext& ctx);
- void OpenApplicationArea(Kernel::HLERequestContext& ctx);
- void GetApplicationArea(Kernel::HLERequestContext& ctx);
- void SetApplicationArea(Kernel::HLERequestContext& ctx);
- void Flush(Kernel::HLERequestContext& ctx);
- void CreateApplicationArea(Kernel::HLERequestContext& ctx);
- void GetTagInfo(Kernel::HLERequestContext& ctx);
- void GetRegisterInfo(Kernel::HLERequestContext& ctx);
- void GetCommonInfo(Kernel::HLERequestContext& ctx);
- void GetModelInfo(Kernel::HLERequestContext& ctx);
- void AttachActivateEvent(Kernel::HLERequestContext& ctx);
- void AttachDeactivateEvent(Kernel::HLERequestContext& ctx);
- void GetState(Kernel::HLERequestContext& ctx);
- void GetDeviceState(Kernel::HLERequestContext& ctx);
- void GetNpadId(Kernel::HLERequestContext& ctx);
- void GetApplicationAreaSize(Kernel::HLERequestContext& ctx);
- void AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx);
- void RecreateApplicationArea(Kernel::HLERequestContext& ctx);
-
- KernelHelpers::ServiceContext service_context;
-
- // TODO(german77): We should have a vector of interfaces
- Module::Interface& nfp_interface;
-
- State state{State::NonInitialized};
- Kernel::KEvent* availability_change_event;
-};
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp
new file mode 100644
index 000000000..b19672560
--- /dev/null
+++ b/src/core/hle/service/nfp/nfp_device.cpp
@@ -0,0 +1,690 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <array>
+#include <atomic>
+
+#include "common/fs/file.h"
+#include "common/fs/path_util.h"
+#include "common/input.h"
+#include "common/logging/log.h"
+#include "common/string_util.h"
+#include "common/tiny_mt.h"
+#include "core/core.h"
+#include "core/hid/emulated_controller.h"
+#include "core/hid/hid_core.h"
+#include "core/hid/hid_types.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/k_event.h"
+#include "core/hle/service/mii/mii_manager.h"
+#include "core/hle/service/mii/types.h"
+#include "core/hle/service/nfp/amiibo_crypto.h"
+#include "core/hle/service/nfp/nfp.h"
+#include "core/hle/service/nfp/nfp_device.h"
+#include "core/hle/service/nfp/nfp_result.h"
+#include "core/hle/service/nfp/nfp_user.h"
+#include "core/hle/service/time/time_manager.h"
+#include "core/hle/service/time/time_zone_content_manager.h"
+#include "core/hle/service/time/time_zone_types.h"
+
+namespace Service::NFP {
+NfpDevice::NfpDevice(Core::HID::NpadIdType npad_id_, Core::System& system_,
+ KernelHelpers::ServiceContext& service_context_,
+ Kernel::KEvent* availability_change_event_)
+ : npad_id{npad_id_}, system{system_}, service_context{service_context_},
+ availability_change_event{availability_change_event_} {
+ activate_event = service_context.CreateEvent("IUser:NFPActivateEvent");
+ deactivate_event = service_context.CreateEvent("IUser:NFPDeactivateEvent");
+ npad_device = system.HIDCore().GetEmulatedController(npad_id);
+
+ Core::HID::ControllerUpdateCallback engine_callback{
+ .on_change = [this](Core::HID::ControllerTriggerType type) { NpadUpdate(type); },
+ .is_npad_service = false,
+ };
+ is_controller_set = true;
+ callback_key = npad_device->SetCallback(engine_callback);
+
+ auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()};
+ current_posix_time = standard_steady_clock.GetCurrentTimePoint(system).time_point;
+}
+
+NfpDevice::~NfpDevice() {
+ if (!is_controller_set) {
+ return;
+ }
+ npad_device->DeleteCallback(callback_key);
+ is_controller_set = false;
+};
+
+void NfpDevice::NpadUpdate(Core::HID::ControllerTriggerType type) {
+ if (type == Core::HID::ControllerTriggerType::Connected ||
+ type == Core::HID::ControllerTriggerType::Disconnected) {
+ availability_change_event->Signal();
+ return;
+ }
+
+ if (type != Core::HID::ControllerTriggerType::Nfc) {
+ return;
+ }
+
+ if (!npad_device->IsConnected()) {
+ return;
+ }
+
+ const auto nfc_status = npad_device->GetNfc();
+ switch (nfc_status.state) {
+ case Common::Input::NfcState::NewAmiibo:
+ LoadAmiibo(nfc_status.data);
+ break;
+ case Common::Input::NfcState::AmiiboRemoved:
+ if (device_state != DeviceState::SearchingForTag) {
+ CloseAmiibo();
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+bool NfpDevice::LoadAmiibo(std::span<const u8> data) {
+ if (device_state != DeviceState::SearchingForTag) {
+ LOG_ERROR(Service_NFP, "Game is not looking for amiibos, current state {}", device_state);
+ return false;
+ }
+
+ if (data.size() != sizeof(EncryptedNTAG215File)) {
+ LOG_ERROR(Service_NFP, "Not an amiibo, size={}", data.size());
+ return false;
+ }
+
+ memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File));
+
+ device_state = DeviceState::TagFound;
+ deactivate_event->GetReadableEvent().Clear();
+ activate_event->Signal();
+ return true;
+}
+
+void NfpDevice::CloseAmiibo() {
+ LOG_INFO(Service_NFP, "Remove amiibo");
+
+ if (device_state == DeviceState::TagMounted) {
+ Unmount();
+ }
+
+ device_state = DeviceState::TagRemoved;
+ encrypted_tag_data = {};
+ tag_data = {};
+ activate_event->GetReadableEvent().Clear();
+ deactivate_event->Signal();
+}
+
+Kernel::KReadableEvent& NfpDevice::GetActivateEvent() const {
+ return activate_event->GetReadableEvent();
+}
+
+Kernel::KReadableEvent& NfpDevice::GetDeactivateEvent() const {
+ return deactivate_event->GetReadableEvent();
+}
+
+void NfpDevice::Initialize() {
+ device_state = npad_device->HasNfc() ? DeviceState::Initialized : DeviceState::Unavailable;
+ encrypted_tag_data = {};
+ tag_data = {};
+}
+
+void NfpDevice::Finalize() {
+ if (device_state == DeviceState::TagMounted) {
+ Unmount();
+ }
+ if (device_state == DeviceState::SearchingForTag || device_state == DeviceState::TagRemoved) {
+ StopDetection();
+ }
+ device_state = DeviceState::Unavailable;
+}
+
+Result NfpDevice::StartDetection(s32 protocol_) {
+ if (device_state != DeviceState::Initialized && device_state != DeviceState::TagRemoved) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ return WrongDeviceState;
+ }
+
+ if (!npad_device->SetPollingMode(Common::Input::PollingMode::NFC)) {
+ LOG_ERROR(Service_NFP, "Nfc not supported");
+ return NfcDisabled;
+ }
+
+ device_state = DeviceState::SearchingForTag;
+ protocol = protocol_;
+ return ResultSuccess;
+}
+
+Result NfpDevice::StopDetection() {
+ npad_device->SetPollingMode(Common::Input::PollingMode::Active);
+
+ if (device_state == DeviceState::Initialized) {
+ return ResultSuccess;
+ }
+
+ if (device_state == DeviceState::TagFound || device_state == DeviceState::TagMounted) {
+ CloseAmiibo();
+ return ResultSuccess;
+ }
+ if (device_state == DeviceState::SearchingForTag || device_state == DeviceState::TagRemoved) {
+ device_state = DeviceState::Initialized;
+ return ResultSuccess;
+ }
+
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ return WrongDeviceState;
+}
+
+Result NfpDevice::Flush() {
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
+ LOG_ERROR(Service_NFP, "Amiibo is read only", device_state);
+ return WrongDeviceState;
+ }
+
+ auto& settings = tag_data.settings;
+
+ const auto& current_date = GetAmiiboDate(current_posix_time);
+ if (settings.write_date.raw_date != current_date.raw_date) {
+ settings.write_date = current_date;
+ settings.crc_counter++;
+ // TODO: Find how to calculate the crc check
+ // settings.crc = CalculateCRC(settings);
+ }
+
+ tag_data.write_counter++;
+
+ if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) {
+ LOG_ERROR(Service_NFP, "Failed to encode data");
+ return WriteAmiiboFailed;
+ }
+
+ std::vector<u8> data(sizeof(encrypted_tag_data));
+ memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data));
+
+ if (!npad_device->WriteNfc(data)) {
+ LOG_ERROR(Service_NFP, "Error writing to file");
+ return WriteAmiiboFailed;
+ }
+
+ is_data_moddified = false;
+
+ return ResultSuccess;
+}
+
+Result NfpDevice::Mount(MountTarget mount_target_) {
+ if (device_state != DeviceState::TagFound) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ return WrongDeviceState;
+ }
+
+ if (!AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) {
+ LOG_ERROR(Service_NFP, "Not an amiibo");
+ return NotAnAmiibo;
+ }
+
+ // Mark amiibos as read only when keys are missing
+ if (!AmiiboCrypto::IsKeyAvailable()) {
+ LOG_ERROR(Service_NFP, "No keys detected");
+ device_state = DeviceState::TagMounted;
+ mount_target = MountTarget::Rom;
+ return ResultSuccess;
+ }
+
+ if (!AmiiboCrypto::DecodeAmiibo(encrypted_tag_data, tag_data)) {
+ LOG_ERROR(Service_NFP, "Can't decode amiibo {}", device_state);
+ return CorruptedData;
+ }
+
+ device_state = DeviceState::TagMounted;
+ mount_target = mount_target_;
+ return ResultSuccess;
+}
+
+Result NfpDevice::Unmount() {
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ // Save data before unloading the amiibo
+ if (is_data_moddified) {
+ Flush();
+ }
+
+ device_state = DeviceState::TagFound;
+ mount_target = MountTarget::None;
+ is_app_area_open = false;
+
+ return ResultSuccess;
+}
+
+Result NfpDevice::GetTagInfo(TagInfo& tag_info) const {
+ if (device_state != DeviceState::TagFound && device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ tag_info = {
+ .uuid = encrypted_tag_data.uuid.uid,
+ .uuid_length = static_cast<u8>(encrypted_tag_data.uuid.uid.size()),
+ .protocol = TagProtocol::TypeA,
+ .tag_type = TagType::Type2,
+ };
+
+ return ResultSuccess;
+}
+
+Result NfpDevice::GetCommonInfo(CommonInfo& common_info) const {
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
+ LOG_ERROR(Service_NFP, "Amiibo is read only", device_state);
+ return WrongDeviceState;
+ }
+
+ const auto& settings = tag_data.settings;
+
+ // TODO: Validate this data
+ common_info = {
+ .last_write_date = settings.write_date.GetWriteDate(),
+ .write_counter = tag_data.write_counter,
+ .version = 0,
+ .application_area_size = sizeof(ApplicationArea),
+ };
+ return ResultSuccess;
+}
+
+Result NfpDevice::GetModelInfo(ModelInfo& model_info) const {
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ const auto& model_info_data = encrypted_tag_data.user_memory.model_info;
+ model_info = {
+ .character_id = model_info_data.character_id,
+ .character_variant = model_info_data.character_variant,
+ .amiibo_type = model_info_data.amiibo_type,
+ .model_number = model_info_data.model_number,
+ .series = model_info_data.series,
+ };
+ return ResultSuccess;
+}
+
+Result NfpDevice::GetRegisterInfo(RegisterInfo& register_info) const {
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
+ LOG_ERROR(Service_NFP, "Amiibo is read only", device_state);
+ return WrongDeviceState;
+ }
+
+ if (tag_data.settings.settings.amiibo_initialized == 0) {
+ return RegistrationIsNotInitialized;
+ }
+
+ Service::Mii::MiiManager manager;
+ const auto& settings = tag_data.settings;
+
+ // TODO: Validate this data
+ register_info = {
+ .mii_char_info = manager.ConvertV3ToCharInfo(tag_data.owner_mii),
+ .creation_date = settings.init_date.GetWriteDate(),
+ .amiibo_name = GetAmiiboName(settings),
+ .font_region = {},
+ };
+
+ return ResultSuccess;
+}
+
+Result NfpDevice::SetNicknameAndOwner(const AmiiboName& amiibo_name) {
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
+ LOG_ERROR(Service_NFP, "Amiibo is read only", device_state);
+ return WrongDeviceState;
+ }
+
+ Service::Mii::MiiManager manager;
+ auto& settings = tag_data.settings;
+
+ settings.init_date = GetAmiiboDate(current_posix_time);
+ settings.write_date = GetAmiiboDate(current_posix_time);
+ settings.crc_counter++;
+ // TODO: Find how to calculate the crc check
+ // settings.crc = CalculateCRC(settings);
+
+ SetAmiiboName(settings, amiibo_name);
+ tag_data.owner_mii = manager.ConvertCharInfoToV3(manager.BuildDefault(0));
+ settings.settings.amiibo_initialized.Assign(1);
+
+ return Flush();
+}
+
+Result NfpDevice::RestoreAmiibo() {
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
+ LOG_ERROR(Service_NFP, "Amiibo is read only", device_state);
+ return WrongDeviceState;
+ }
+
+ // TODO: Load amiibo from backup on system
+ LOG_ERROR(Service_NFP, "Not Implemented");
+ return ResultSuccess;
+}
+
+Result NfpDevice::DeleteAllData() {
+ const auto result = DeleteApplicationArea();
+ if (result.IsError()) {
+ return result;
+ }
+
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ Common::TinyMT rng{};
+ rng.GenerateRandomBytes(&tag_data.owner_mii, sizeof(tag_data.owner_mii));
+ tag_data.settings.settings.amiibo_initialized.Assign(0);
+
+ return Flush();
+}
+
+Result NfpDevice::OpenApplicationArea(u32 access_id) {
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
+ LOG_ERROR(Service_NFP, "Amiibo is read only", device_state);
+ return WrongDeviceState;
+ }
+
+ if (tag_data.settings.settings.appdata_initialized.Value() == 0) {
+ LOG_WARNING(Service_NFP, "Application area is not initialized");
+ return ApplicationAreaIsNotInitialized;
+ }
+
+ if (tag_data.application_area_id != access_id) {
+ LOG_WARNING(Service_NFP, "Wrong application area id");
+ return WrongApplicationAreaId;
+ }
+
+ is_app_area_open = true;
+
+ return ResultSuccess;
+}
+
+Result NfpDevice::GetApplicationArea(std::vector<u8>& data) const {
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
+ LOG_ERROR(Service_NFP, "Amiibo is read only", device_state);
+ return WrongDeviceState;
+ }
+
+ if (!is_app_area_open) {
+ LOG_ERROR(Service_NFP, "Application area is not open");
+ return WrongDeviceState;
+ }
+
+ if (tag_data.settings.settings.appdata_initialized.Value() == 0) {
+ LOG_ERROR(Service_NFP, "Application area is not initialized");
+ return ApplicationAreaIsNotInitialized;
+ }
+
+ if (data.size() > sizeof(ApplicationArea)) {
+ data.resize(sizeof(ApplicationArea));
+ }
+
+ memcpy(data.data(), tag_data.application_area.data(), data.size());
+
+ return ResultSuccess;
+}
+
+Result NfpDevice::SetApplicationArea(std::span<const u8> data) {
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
+ LOG_ERROR(Service_NFP, "Amiibo is read only", device_state);
+ return WrongDeviceState;
+ }
+
+ if (!is_app_area_open) {
+ LOG_ERROR(Service_NFP, "Application area is not open");
+ return WrongDeviceState;
+ }
+
+ if (tag_data.settings.settings.appdata_initialized.Value() == 0) {
+ LOG_ERROR(Service_NFP, "Application area is not initialized");
+ return ApplicationAreaIsNotInitialized;
+ }
+
+ if (data.size() > sizeof(ApplicationArea)) {
+ LOG_ERROR(Service_NFP, "Wrong data size {}", data.size());
+ return ResultUnknown;
+ }
+
+ Common::TinyMT rng{};
+ std::memcpy(tag_data.application_area.data(), data.data(), data.size());
+ // Fill remaining data with random numbers
+ rng.GenerateRandomBytes(tag_data.application_area.data() + data.size(),
+ sizeof(ApplicationArea) - data.size());
+
+ tag_data.applicaton_write_counter++;
+ is_data_moddified = true;
+
+ return ResultSuccess;
+}
+
+Result NfpDevice::CreateApplicationArea(u32 access_id, std::span<const u8> data) {
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (tag_data.settings.settings.appdata_initialized.Value() != 0) {
+ LOG_ERROR(Service_NFP, "Application area already exist");
+ return ApplicationAreaExist;
+ }
+
+ return RecreateApplicationArea(access_id, data);
+}
+
+Result NfpDevice::RecreateApplicationArea(u32 access_id, std::span<const u8> data) {
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
+ LOG_ERROR(Service_NFP, "Amiibo is read only", device_state);
+ return WrongDeviceState;
+ }
+
+ if (data.size() > sizeof(ApplicationArea)) {
+ LOG_ERROR(Service_NFP, "Wrong data size {}", data.size());
+ return WrongApplicationAreaSize;
+ }
+
+ Common::TinyMT rng{};
+ std::memcpy(tag_data.application_area.data(), data.data(), data.size());
+ // Fill remaining data with random numbers
+ rng.GenerateRandomBytes(tag_data.application_area.data() + data.size(),
+ sizeof(ApplicationArea) - data.size());
+
+ // TODO: Investigate why the title id needs to be moddified
+ tag_data.title_id = system.GetCurrentProcessProgramID();
+ tag_data.title_id = tag_data.title_id | 0x30000000ULL;
+ tag_data.settings.settings.appdata_initialized.Assign(1);
+ tag_data.application_area_id = access_id;
+ tag_data.applicaton_write_counter++;
+ tag_data.unknown = {};
+
+ return Flush();
+}
+
+Result NfpDevice::DeleteApplicationArea() {
+ if (device_state != DeviceState::TagMounted) {
+ LOG_ERROR(Service_NFP, "Wrong device state {}", device_state);
+ if (device_state == DeviceState::TagRemoved) {
+ return TagRemoved;
+ }
+ return WrongDeviceState;
+ }
+
+ if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
+ LOG_ERROR(Service_NFP, "Amiibo is read only", device_state);
+ return WrongDeviceState;
+ }
+
+ Common::TinyMT rng{};
+ rng.GenerateRandomBytes(tag_data.application_area.data(), sizeof(ApplicationArea));
+ rng.GenerateRandomBytes(&tag_data.title_id, sizeof(u64));
+ rng.GenerateRandomBytes(&tag_data.application_area_id, sizeof(u32));
+ tag_data.settings.settings.appdata_initialized.Assign(0);
+ tag_data.applicaton_write_counter++;
+ tag_data.unknown = {};
+
+ return Flush();
+}
+
+u64 NfpDevice::GetHandle() const {
+ // Generate a handle based of the npad id
+ return static_cast<u64>(npad_id);
+}
+
+u32 NfpDevice::GetApplicationAreaSize() const {
+ return sizeof(ApplicationArea);
+}
+
+DeviceState NfpDevice::GetCurrentState() const {
+ return device_state;
+}
+
+Core::HID::NpadIdType NfpDevice::GetNpadId() const {
+ return npad_id;
+}
+
+AmiiboName NfpDevice::GetAmiiboName(const AmiiboSettings& settings) const {
+ std::array<char16_t, amiibo_name_length> settings_amiibo_name{};
+ AmiiboName amiibo_name{};
+
+ // Convert from big endian to little endian
+ for (std::size_t i = 0; i < amiibo_name_length; i++) {
+ settings_amiibo_name[i] = static_cast<u16>(settings.amiibo_name[i]);
+ }
+
+ // Convert from utf16 to utf8
+ const auto amiibo_name_utf8 = Common::UTF16ToUTF8(settings_amiibo_name.data());
+ memcpy(amiibo_name.data(), amiibo_name_utf8.data(), amiibo_name_utf8.size());
+
+ return amiibo_name;
+}
+
+void NfpDevice::SetAmiiboName(AmiiboSettings& settings, const AmiiboName& amiibo_name) {
+ std::array<char16_t, amiibo_name_length> settings_amiibo_name{};
+
+ // Convert from utf8 to utf16
+ const auto amiibo_name_utf16 = Common::UTF8ToUTF16(amiibo_name.data());
+ memcpy(settings_amiibo_name.data(), amiibo_name_utf16.data(),
+ amiibo_name_utf16.size() * sizeof(char16_t));
+
+ // Convert from little endian to big endian
+ for (std::size_t i = 0; i < amiibo_name_length; i++) {
+ settings.amiibo_name[i] = static_cast<u16_be>(settings_amiibo_name[i]);
+ }
+}
+
+AmiiboDate NfpDevice::GetAmiiboDate(s64 posix_time) const {
+ const auto& time_zone_manager =
+ system.GetTimeManager().GetTimeZoneContentManager().GetTimeZoneManager();
+ Time::TimeZone::CalendarInfo calendar_info{};
+ AmiiboDate amiibo_date{};
+
+ amiibo_date.SetYear(2000);
+ amiibo_date.SetMonth(1);
+ amiibo_date.SetDay(1);
+
+ if (time_zone_manager.ToCalendarTime({}, posix_time, calendar_info) == ResultSuccess) {
+ amiibo_date.SetYear(calendar_info.time.year);
+ amiibo_date.SetMonth(calendar_info.time.month);
+ amiibo_date.SetDay(calendar_info.time.day);
+ }
+
+ return amiibo_date;
+}
+
+} // namespace Service::NFP
diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h
new file mode 100644
index 000000000..76d0e9ae4
--- /dev/null
+++ b/src/core/hle/service/nfp/nfp_device.h
@@ -0,0 +1,100 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <array>
+#include <vector>
+
+#include "common/common_funcs.h"
+#include "core/hle/service/kernel_helpers.h"
+#include "core/hle/service/nfp/nfp_types.h"
+#include "core/hle/service/service.h"
+
+namespace Kernel {
+class KEvent;
+class KReadableEvent;
+} // namespace Kernel
+
+namespace Core {
+class System;
+} // namespace Core
+
+namespace Core::HID {
+class EmulatedController;
+enum class ControllerTriggerType;
+enum class NpadIdType : u32;
+} // namespace Core::HID
+
+namespace Service::NFP {
+class NfpDevice {
+public:
+ NfpDevice(Core::HID::NpadIdType npad_id_, Core::System& system_,
+ KernelHelpers::ServiceContext& service_context_,
+ Kernel::KEvent* availability_change_event_);
+ ~NfpDevice();
+
+ void Initialize();
+ void Finalize();
+
+ Result StartDetection(s32 protocol_);
+ Result StopDetection();
+ Result Mount(MountTarget mount_target);
+ Result Unmount();
+ Result Flush();
+
+ Result GetTagInfo(TagInfo& tag_info) const;
+ Result GetCommonInfo(CommonInfo& common_info) const;
+ Result GetModelInfo(ModelInfo& model_info) const;
+ Result GetRegisterInfo(RegisterInfo& register_info) const;
+
+ Result SetNicknameAndOwner(const AmiiboName& amiibo_name);
+ Result RestoreAmiibo();
+ Result DeleteAllData();
+
+ Result OpenApplicationArea(u32 access_id);
+ Result GetApplicationArea(std::vector<u8>& data) const;
+ Result SetApplicationArea(std::span<const u8> data);
+ Result CreateApplicationArea(u32 access_id, std::span<const u8> data);
+ Result RecreateApplicationArea(u32 access_id, std::span<const u8> data);
+ Result DeleteApplicationArea();
+
+ u64 GetHandle() const;
+ u32 GetApplicationAreaSize() const;
+ DeviceState GetCurrentState() const;
+ Core::HID::NpadIdType GetNpadId() const;
+
+ Kernel::KReadableEvent& GetActivateEvent() const;
+ Kernel::KReadableEvent& GetDeactivateEvent() const;
+
+private:
+ void NpadUpdate(Core::HID::ControllerTriggerType type);
+ bool LoadAmiibo(std::span<const u8> data);
+ void CloseAmiibo();
+
+ AmiiboName GetAmiiboName(const AmiiboSettings& settings) const;
+ void SetAmiiboName(AmiiboSettings& settings, const AmiiboName& amiibo_name);
+ AmiiboDate GetAmiiboDate(s64 posix_time) const;
+
+ bool is_controller_set{};
+ int callback_key;
+ const Core::HID::NpadIdType npad_id;
+ Core::System& system;
+ Core::HID::EmulatedController* npad_device = nullptr;
+ KernelHelpers::ServiceContext& service_context;
+ Kernel::KEvent* activate_event = nullptr;
+ Kernel::KEvent* deactivate_event = nullptr;
+ Kernel::KEvent* availability_change_event = nullptr;
+
+ bool is_data_moddified{};
+ bool is_app_area_open{};
+ s32 protocol{};
+ s64 current_posix_time{};
+ MountTarget mount_target{MountTarget::None};
+ DeviceState device_state{DeviceState::Unavailable};
+
+ NTAG215File tag_data{};
+ EncryptedNTAG215File encrypted_tag_data{};
+};
+
+} // namespace Service::NFP
diff --git a/src/core/hle/service/nfp/nfp_result.h b/src/core/hle/service/nfp/nfp_result.h
new file mode 100644
index 000000000..d8e4cf094
--- /dev/null
+++ b/src/core/hle/service/nfp/nfp_result.h
@@ -0,0 +1,24 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "core/hle/result.h"
+
+namespace Service::NFP {
+
+constexpr Result DeviceNotFound(ErrorModule::NFP, 64);
+constexpr Result InvalidArgument(ErrorModule::NFP, 65);
+constexpr Result WrongApplicationAreaSize(ErrorModule::NFP, 68);
+constexpr Result WrongDeviceState(ErrorModule::NFP, 73);
+constexpr Result NfcDisabled(ErrorModule::NFP, 80);
+constexpr Result WriteAmiiboFailed(ErrorModule::NFP, 88);
+constexpr Result TagRemoved(ErrorModule::NFP, 97);
+constexpr Result RegistrationIsNotInitialized(ErrorModule::NFP, 120);
+constexpr Result ApplicationAreaIsNotInitialized(ErrorModule::NFP, 128);
+constexpr Result CorruptedData(ErrorModule::NFP, 144);
+constexpr Result WrongApplicationAreaId(ErrorModule::NFP, 152);
+constexpr Result ApplicationAreaExist(ErrorModule::NFP, 168);
+constexpr Result NotAnAmiibo(ErrorModule::NFP, 178);
+
+} // namespace Service::NFP
diff --git a/src/core/hle/service/nfp/amiibo_types.h b/src/core/hle/service/nfp/nfp_types.h
index bf2de811a..63d5917cb 100644
--- a/src/core/hle/service/nfp/amiibo_types.h
+++ b/src/core/hle/service/nfp/nfp_types.h
@@ -5,6 +5,7 @@
#include <array>
+#include "common/swap.h"
#include "core/hle/service/mii/types.h"
namespace Service::NFP {
@@ -16,18 +17,13 @@ enum class ServiceType : u32 {
System,
};
-enum class State : u32 {
- NonInitialized,
- Initialized,
-};
-
enum class DeviceState : u32 {
Initialized,
SearchingForTag,
TagFound,
TagRemoved,
TagMounted,
- Unaviable,
+ Unavailable,
Finalized,
};
@@ -36,6 +32,7 @@ enum class ModelType : u32 {
};
enum class MountTarget : u32 {
+ None,
Rom,
Ram,
All,
@@ -73,21 +70,101 @@ enum class AmiiboSeries : u8 {
Diablo,
};
-using TagUuid = std::array<u8, 10>;
+enum class TagType : u32 {
+ None,
+ Type1, // ISO14443A RW 96-2k bytes 106kbit/s
+ Type2, // ISO14443A RW/RO 540 bytes 106kbit/s
+ Type3, // Sony Felica RW/RO 2k bytes 212kbit/s
+ Type4, // ISO14443A RW/RO 4k-32k bytes 424kbit/s
+ Type5, // ISO15693 RW/RO 540 bytes 106kbit/s
+};
+
+enum class PackedTagType : u8 {
+ None,
+ Type1, // ISO14443A RW 96-2k bytes 106kbit/s
+ Type2, // ISO14443A RW/RO 540 bytes 106kbit/s
+ Type3, // Sony Felica RW/RO 2k bytes 212kbit/s
+ Type4, // ISO14443A RW/RO 4k-32k bytes 424kbit/s
+ Type5, // ISO15693 RW/RO 540 bytes 106kbit/s
+};
+
+enum class TagProtocol : u32 {
+ None,
+ TypeA, // ISO14443A
+ TypeB, // ISO14443B
+ TypeF, // Sony Felica
+};
+
+using UniqueSerialNumber = std::array<u8, 7>;
+using LockBytes = std::array<u8, 2>;
using HashData = std::array<u8, 0x20>;
using ApplicationArea = std::array<u8, 0xD8>;
+using AmiiboName = std::array<char, (amiibo_name_length * 4) + 1>;
+
+struct TagUuid {
+ UniqueSerialNumber uid;
+ u8 nintendo_id;
+ LockBytes lock_bytes;
+};
+static_assert(sizeof(TagUuid) == 10, "TagUuid is an invalid size");
+
+struct WriteDate {
+ u16 year;
+ u8 month;
+ u8 day;
+};
+static_assert(sizeof(WriteDate) == 0x4, "WriteDate is an invalid size");
struct AmiiboDate {
u16 raw_date{};
+ u16 GetValue() const {
+ return Common::swap16(raw_date);
+ }
+
u16 GetYear() const {
- return static_cast<u16>(((raw_date & 0xFE00) >> 9) + 2000);
+ return static_cast<u16>(((GetValue() & 0xFE00) >> 9) + 2000);
}
u8 GetMonth() const {
- return static_cast<u8>(((raw_date & 0x01E0) >> 5) - 1);
+ return static_cast<u8>((GetValue() & 0x01E0) >> 5);
}
u8 GetDay() const {
- return static_cast<u8>(raw_date & 0x001F);
+ return static_cast<u8>(GetValue() & 0x001F);
+ }
+
+ WriteDate GetWriteDate() const {
+ if (!IsValidDate()) {
+ return {
+ .year = 2000,
+ .month = 1,
+ .day = 1,
+ };
+ }
+ return {
+ .year = GetYear(),
+ .month = GetMonth(),
+ .day = GetDay(),
+ };
+ }
+
+ void SetYear(u16 year) {
+ const u16 year_converted = static_cast<u16>((year - 2000) << 9);
+ raw_date = Common::swap16((GetValue() & ~0xFE00) | year_converted);
+ }
+ void SetMonth(u8 month) {
+ const u16 month_converted = static_cast<u16>(month << 5);
+ raw_date = Common::swap16((GetValue() & ~0x01E0) | month_converted);
+ }
+ void SetDay(u8 day) {
+ const u16 day_converted = static_cast<u16>(day);
+ raw_date = Common::swap16((GetValue() & ~0x001F) | day_converted);
+ }
+
+ bool IsValidDate() const {
+ const bool is_day_valid = GetDay() > 0 && GetDay() < 32;
+ const bool is_month_valid = GetMonth() > 0 && GetMonth() < 13;
+ const bool is_year_valid = GetYear() >= 2000;
+ return is_year_valid && is_month_valid && is_day_valid;
}
};
static_assert(sizeof(AmiiboDate) == 2, "AmiiboDate is an invalid size");
@@ -117,9 +194,9 @@ struct AmiiboModelInfo {
u16 character_id;
u8 character_variant;
AmiiboType amiibo_type;
- u16 model_number;
+ u16_be model_number;
AmiiboSeries series;
- u8 constant_value; // Must be 02
+ PackedTagType tag_type;
INSERT_PADDING_BYTES(0x4); // Unknown
};
static_assert(sizeof(AmiiboModelInfo) == 0xC, "AmiiboModelInfo is an invalid size");
@@ -134,7 +211,7 @@ static_assert(sizeof(NTAG215Password) == 0x8, "NTAG215Password is an invalid siz
#pragma pack(1)
struct EncryptedAmiiboFile {
u8 constant_value; // Must be A5
- u16 write_counter; // Number of times the amiibo has been written?
+ u16_be write_counter; // Number of times the amiibo has been written?
INSERT_PADDING_BYTES(0x1); // Unknown 1
AmiiboSettings settings; // Encrypted amiibo settings
HashData hmac_tag; // Hash
@@ -146,18 +223,18 @@ struct EncryptedAmiiboFile {
u16_be applicaton_write_counter; // Encrypted Counter
u32_be application_area_id; // Encrypted Game id
std::array<u8, 0x2> unknown;
- HashData hash; // Probably a SHA256-HMAC hash?
+ std::array<u32, 0x8> unknown2;
ApplicationArea application_area; // Encrypted Game data
};
static_assert(sizeof(EncryptedAmiiboFile) == 0x1F8, "AmiiboFile is an invalid size");
struct NTAG215File {
- std::array<u8, 0x2> uuid2;
+ LockBytes lock_bytes; // Tag UUID
u16 static_lock; // Set defined pages as read only
u32 compability_container; // Defines available memory
HashData hmac_data; // Hash
u8 constant_value; // Must be A5
- u16 write_counter; // Number of times the amiibo has been written?
+ u16_be write_counter; // Number of times the amiibo has been written?
INSERT_PADDING_BYTES(0x1); // Unknown 1
AmiiboSettings settings;
Service::Mii::Ver3StoreData owner_mii; // Encrypted Mii data
@@ -165,10 +242,11 @@ struct NTAG215File {
u16_be applicaton_write_counter; // Encrypted Counter
u32_be application_area_id;
std::array<u8, 0x2> unknown;
- HashData hash; // Probably a SHA256-HMAC hash?
+ std::array<u32, 0x8> unknown2;
ApplicationArea application_area; // Encrypted Game data
HashData hmac_tag; // Hash
- std::array<u8, 0x8> uuid;
+ UniqueSerialNumber uid; // Unique serial number
+ u8 nintendo_id; // Tag UUID
AmiiboModelInfo model_info;
HashData keygen_salt; // Salt
u32 dynamic_lock; // Dynamic lock
@@ -194,4 +272,44 @@ static_assert(sizeof(EncryptedNTAG215File) == 0x21C, "EncryptedNTAG215File is an
static_assert(std::is_trivially_copyable_v<EncryptedNTAG215File>,
"EncryptedNTAG215File must be trivially copyable.");
+struct TagInfo {
+ UniqueSerialNumber uuid;
+ INSERT_PADDING_BYTES(0x3);
+ u8 uuid_length;
+ INSERT_PADDING_BYTES(0x15);
+ TagProtocol protocol;
+ TagType tag_type;
+ INSERT_PADDING_BYTES(0x30);
+};
+static_assert(sizeof(TagInfo) == 0x58, "TagInfo is an invalid size");
+
+struct CommonInfo {
+ WriteDate last_write_date;
+ u16 write_counter;
+ u8 version;
+ INSERT_PADDING_BYTES(0x1);
+ u32 application_area_size;
+ INSERT_PADDING_BYTES(0x34);
+};
+static_assert(sizeof(CommonInfo) == 0x40, "CommonInfo is an invalid size");
+
+struct ModelInfo {
+ u16 character_id;
+ u8 character_variant;
+ AmiiboType amiibo_type;
+ u16 model_number;
+ AmiiboSeries series;
+ INSERT_PADDING_BYTES(0x39); // Unknown
+};
+static_assert(sizeof(ModelInfo) == 0x40, "ModelInfo is an invalid size");
+
+struct RegisterInfo {
+ Service::Mii::CharInfo mii_char_info;
+ WriteDate creation_date;
+ AmiiboName amiibo_name;
+ u8 font_region;
+ INSERT_PADDING_BYTES(0x7A);
+};
+static_assert(sizeof(RegisterInfo) == 0x100, "RegisterInfo is an invalid size");
+
} // namespace Service::NFP
diff --git a/src/core/hle/service/nfp/nfp_user.cpp b/src/core/hle/service/nfp/nfp_user.cpp
index 2d7b156cf..33e2ef518 100644
--- a/src/core/hle/service/nfp/nfp_user.cpp
+++ b/src/core/hle/service/nfp/nfp_user.cpp
@@ -1,18 +1,671 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include <array>
+#include <atomic>
+
+#include "common/logging/log.h"
+#include "core/core.h"
+#include "core/hid/hid_types.h"
+#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/k_event.h"
+#include "core/hle/service/nfp/nfp_device.h"
+#include "core/hle/service/nfp/nfp_result.h"
#include "core/hle/service/nfp/nfp_user.h"
namespace Service::NFP {
-NFP_User::NFP_User(std::shared_ptr<Module> module_, Core::System& system_)
- : Interface(std::move(module_), system_, "nfp:user") {
+IUser::IUser(Core::System& system_)
+ : ServiceFramework{system_, "NFP::IUser"}, service_context{system_, service_name} {
static const FunctionInfo functions[] = {
- {0, &NFP_User::CreateUserInterface, "CreateUserInterface"},
+ {0, &IUser::Initialize, "Initialize"},
+ {1, &IUser::Finalize, "Finalize"},
+ {2, &IUser::ListDevices, "ListDevices"},
+ {3, &IUser::StartDetection, "StartDetection"},
+ {4, &IUser::StopDetection, "StopDetection"},
+ {5, &IUser::Mount, "Mount"},
+ {6, &IUser::Unmount, "Unmount"},
+ {7, &IUser::OpenApplicationArea, "OpenApplicationArea"},
+ {8, &IUser::GetApplicationArea, "GetApplicationArea"},
+ {9, &IUser::SetApplicationArea, "SetApplicationArea"},
+ {10, &IUser::Flush, "Flush"},
+ {11, &IUser::Restore, "Restore"},
+ {12, &IUser::CreateApplicationArea, "CreateApplicationArea"},
+ {13, &IUser::GetTagInfo, "GetTagInfo"},
+ {14, &IUser::GetRegisterInfo, "GetRegisterInfo"},
+ {15, &IUser::GetCommonInfo, "GetCommonInfo"},
+ {16, &IUser::GetModelInfo, "GetModelInfo"},
+ {17, &IUser::AttachActivateEvent, "AttachActivateEvent"},
+ {18, &IUser::AttachDeactivateEvent, "AttachDeactivateEvent"},
+ {19, &IUser::GetState, "GetState"},
+ {20, &IUser::GetDeviceState, "GetDeviceState"},
+ {21, &IUser::GetNpadId, "GetNpadId"},
+ {22, &IUser::GetApplicationAreaSize, "GetApplicationAreaSize"},
+ {23, &IUser::AttachAvailabilityChangeEvent, "AttachAvailabilityChangeEvent"},
+ {24, &IUser::RecreateApplicationArea, "RecreateApplicationArea"},
};
RegisterHandlers(functions);
+
+ availability_change_event = service_context.CreateEvent("IUser:AvailabilityChangeEvent");
+
+ for (u32 device_index = 0; device_index < 10; device_index++) {
+ devices[device_index] =
+ std::make_shared<NfpDevice>(Core::HID::IndexToNpadIdType(device_index), system,
+ service_context, availability_change_event);
+ }
+}
+
+void IUser::Initialize(Kernel::HLERequestContext& ctx) {
+ LOG_INFO(Service_NFC, "called");
+
+ state = State::Initialized;
+
+ for (auto& device : devices) {
+ device->Initialize();
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2, 0};
+ rb.Push(ResultSuccess);
+}
+
+void IUser::Finalize(Kernel::HLERequestContext& ctx) {
+ LOG_INFO(Service_NFP, "called");
+
+ state = State::NonInitialized;
+
+ for (auto& device : devices) {
+ device->Finalize();
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IUser::ListDevices(Kernel::HLERequestContext& ctx) {
+ LOG_INFO(Service_NFP, "called");
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ if (!ctx.CanWriteBuffer()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(InvalidArgument);
+ return;
+ }
+
+ if (ctx.GetWriteBufferSize() == 0) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(InvalidArgument);
+ return;
+ }
+
+ std::vector<u64> nfp_devices;
+ const std::size_t max_allowed_devices = ctx.GetWriteBufferSize() / sizeof(u64);
+
+ for (auto& device : devices) {
+ if (nfp_devices.size() >= max_allowed_devices) {
+ continue;
+ }
+ if (device->GetCurrentState() != DeviceState::Unavailable) {
+ nfp_devices.push_back(device->GetHandle());
+ }
+ }
+
+ if (nfp_devices.size() == 0) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ ctx.WriteBuffer(nfp_devices);
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(static_cast<s32>(nfp_devices.size()));
+}
+
+void IUser::StartDetection(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ const auto nfp_protocol{rp.Pop<s32>()};
+ LOG_INFO(Service_NFP, "called, device_handle={}, nfp_protocol={}", device_handle, nfp_protocol);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ const auto result = device.value()->StartDetection(nfp_protocol);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IUser::StopDetection(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ const auto result = device.value()->StopDetection();
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IUser::Mount(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ const auto model_type{rp.PopEnum<ModelType>()};
+ const auto mount_target{rp.PopEnum<MountTarget>()};
+ LOG_INFO(Service_NFP, "called, device_handle={}, model_type={}, mount_target={}", device_handle,
+ model_type, mount_target);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ const auto result = device.value()->Mount(mount_target);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IUser::Unmount(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ const auto result = device.value()->Unmount();
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IUser::OpenApplicationArea(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ const auto access_id{rp.Pop<u32>()};
+ LOG_INFO(Service_NFP, "called, device_handle={}, access_id={}", device_handle, access_id);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ const auto result = device.value()->OpenApplicationArea(access_id);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IUser::GetApplicationArea(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ const auto data_size = ctx.GetWriteBufferSize();
+ LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ if (!ctx.CanWriteBuffer()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(InvalidArgument);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ std::vector<u8> data(data_size);
+ const auto result = device.value()->GetApplicationArea(data);
+ ctx.WriteBuffer(data);
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(result);
+ rb.Push(static_cast<u32>(data_size));
+}
+
+void IUser::SetApplicationArea(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ const auto data{ctx.ReadBuffer()};
+ LOG_INFO(Service_NFP, "called, device_handle={}, data_size={}", device_handle, data.size());
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ if (!ctx.CanReadBuffer()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(InvalidArgument);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ const auto result = device.value()->SetApplicationArea(data);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IUser::Flush(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ const auto result = device.value()->Flush();
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IUser::Restore(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_WARNING(Service_NFP, "(STUBBED) called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ const auto result = device.value()->RestoreAmiibo();
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IUser::CreateApplicationArea(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ const auto access_id{rp.Pop<u32>()};
+ const auto data{ctx.ReadBuffer()};
+ LOG_INFO(Service_NFP, "called, device_handle={}, data_size={}, access_id={}", device_handle,
+ access_id, data.size());
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ if (!ctx.CanReadBuffer()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(InvalidArgument);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ const auto result = device.value()->CreateApplicationArea(access_id, data);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IUser::GetTagInfo(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ TagInfo tag_info{};
+ const auto result = device.value()->GetTagInfo(tag_info);
+ ctx.WriteBuffer(tag_info);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IUser::GetRegisterInfo(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ RegisterInfo register_info{};
+ const auto result = device.value()->GetRegisterInfo(register_info);
+ ctx.WriteBuffer(register_info);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IUser::GetCommonInfo(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ CommonInfo common_info{};
+ const auto result = device.value()->GetCommonInfo(common_info);
+ ctx.WriteBuffer(common_info);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IUser::GetModelInfo(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_INFO(Service_NFP, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ ModelInfo model_info{};
+ const auto result = device.value()->GetModelInfo(model_info);
+ ctx.WriteBuffer(model_info);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+void IUser::AttachActivateEvent(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(device.value()->GetActivateEvent());
+}
+
+void IUser::AttachDeactivateEvent(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(device.value()->GetDeactivateEvent());
+}
+
+void IUser::GetState(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_NFC, "called");
+
+ IPC::ResponseBuilder rb{ctx, 3, 0};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(state);
+}
+
+void IUser::GetDeviceState(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(device.value()->GetCurrentState());
+}
+
+void IUser::GetNpadId(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.PushEnum(device.value()->GetNpadId());
+}
+
+void IUser::GetApplicationAreaSize(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ LOG_DEBUG(Service_NFP, "called, device_handle={}", device_handle);
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(device.value()->GetApplicationAreaSize());
}
-NFP_User::~NFP_User() = default;
+void IUser::AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx) {
+ LOG_INFO(Service_NFP, "called");
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(availability_change_event->GetReadableEvent());
+}
+
+void IUser::RecreateApplicationArea(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto device_handle{rp.Pop<u64>()};
+ const auto access_id{rp.Pop<u32>()};
+ const auto data{ctx.ReadBuffer()};
+ LOG_INFO(Service_NFP, "called, device_handle={}, data_size={}, access_id={}", device_handle,
+ access_id, data.size());
+
+ if (state == State::NonInitialized) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(NfcDisabled);
+ return;
+ }
+
+ auto device = GetNfpDevice(device_handle);
+
+ if (!device.has_value()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(DeviceNotFound);
+ return;
+ }
+
+ const auto result = device.value()->RecreateApplicationArea(access_id, data);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
+std::optional<std::shared_ptr<NfpDevice>> IUser::GetNfpDevice(u64 handle) {
+ for (auto& device : devices) {
+ if (device->GetHandle() == handle) {
+ return device;
+ }
+ }
+ return std::nullopt;
+}
} // namespace Service::NFP
diff --git a/src/core/hle/service/nfp/nfp_user.h b/src/core/hle/service/nfp/nfp_user.h
index 519ff56ee..47aff3695 100644
--- a/src/core/hle/service/nfp/nfp_user.h
+++ b/src/core/hle/service/nfp/nfp_user.h
@@ -3,14 +3,56 @@
#pragma once
-#include "core/hle/service/nfp/nfp.h"
+#include "core/hle/service/kernel_helpers.h"
+#include "core/hle/service/service.h"
namespace Service::NFP {
+class NfpDevice;
-class NFP_User final : public Module::Interface {
+class IUser final : public ServiceFramework<IUser> {
public:
- explicit NFP_User(std::shared_ptr<Module> module_, Core::System& system_);
- ~NFP_User() override;
+ explicit IUser(Core::System& system_);
+
+private:
+ enum class State : u32 {
+ NonInitialized,
+ Initialized,
+ };
+
+ void Initialize(Kernel::HLERequestContext& ctx);
+ void Finalize(Kernel::HLERequestContext& ctx);
+ void ListDevices(Kernel::HLERequestContext& ctx);
+ void StartDetection(Kernel::HLERequestContext& ctx);
+ void StopDetection(Kernel::HLERequestContext& ctx);
+ void Mount(Kernel::HLERequestContext& ctx);
+ void Unmount(Kernel::HLERequestContext& ctx);
+ void OpenApplicationArea(Kernel::HLERequestContext& ctx);
+ void GetApplicationArea(Kernel::HLERequestContext& ctx);
+ void SetApplicationArea(Kernel::HLERequestContext& ctx);
+ void Flush(Kernel::HLERequestContext& ctx);
+ void Restore(Kernel::HLERequestContext& ctx);
+ void CreateApplicationArea(Kernel::HLERequestContext& ctx);
+ void GetTagInfo(Kernel::HLERequestContext& ctx);
+ void GetRegisterInfo(Kernel::HLERequestContext& ctx);
+ void GetCommonInfo(Kernel::HLERequestContext& ctx);
+ void GetModelInfo(Kernel::HLERequestContext& ctx);
+ void AttachActivateEvent(Kernel::HLERequestContext& ctx);
+ void AttachDeactivateEvent(Kernel::HLERequestContext& ctx);
+ void GetState(Kernel::HLERequestContext& ctx);
+ void GetDeviceState(Kernel::HLERequestContext& ctx);
+ void GetNpadId(Kernel::HLERequestContext& ctx);
+ void GetApplicationAreaSize(Kernel::HLERequestContext& ctx);
+ void AttachAvailabilityChangeEvent(Kernel::HLERequestContext& ctx);
+ void RecreateApplicationArea(Kernel::HLERequestContext& ctx);
+
+ std::optional<std::shared_ptr<NfpDevice>> GetNfpDevice(u64 handle);
+
+ KernelHelpers::ServiceContext service_context;
+
+ std::array<std::shared_ptr<NfpDevice>, 10> devices{};
+
+ State state{State::NonInitialized};
+ Kernel::KEvent* availability_change_event;
};
} // namespace Service::NFP
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index b2bb7426d..5a8a91e0b 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -328,7 +328,7 @@ private:
void StartTask(Kernel::HLERequestContext& ctx) {
// No need to connect to the internet, just finish the task straight away.
LOG_DEBUG(Service_NIM, "called");
- finished_event->GetWritableEvent().Signal();
+ finished_event->Signal();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
@@ -350,7 +350,7 @@ private:
void Cancel(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_NIM, "called");
- finished_event->GetWritableEvent().Clear();
+ finished_event->Clear();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index f7318c3cb..f59a1a63d 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -8,6 +8,7 @@
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/vfs.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/service/glue/glue_manager.h"
#include "core/hle/service/ns/errors.h"
#include "core/hle/service/ns/iplatform_service_manager.h"
#include "core/hle/service/ns/language.h"
@@ -581,7 +582,7 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
: ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
- {0, nullptr, "GetApplicationControlData"},
+ {0, &IReadOnlyApplicationControlDataInterface::GetApplicationControlData, "GetApplicationControlData"},
{1, nullptr, "GetApplicationDesiredLanguage"},
{2, nullptr, "ConvertApplicationLanguageToLanguageCode"},
{3, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
@@ -594,6 +595,33 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default;
+void IReadOnlyApplicationControlDataInterface::GetApplicationControlData(
+ Kernel::HLERequestContext& ctx) {
+ enum class ApplicationControlSource : u8 {
+ CacheOnly,
+ Storage,
+ StorageOnly,
+ };
+
+ struct RequestParameters {
+ ApplicationControlSource source;
+ u64 application_id;
+ };
+ static_assert(sizeof(RequestParameters) == 0x10, "RequestParameters has incorrect size.");
+
+ IPC::RequestParser rp{ctx};
+ const auto parameters{rp.PopRaw<RequestParameters>()};
+ const auto nacp_data{system.GetARPManager().GetControlProperty(parameters.application_id)};
+ const auto result = nacp_data ? ResultSuccess : ResultUnknown;
+
+ if (nacp_data) {
+ ctx.WriteBuffer(nacp_data->data(), nacp_data->size());
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(result);
+}
+
NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} {
// clang-format off
static const FunctionInfo functions[] = {
diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h
index 4dc191518..9c18e935c 100644
--- a/src/core/hle/service/ns/ns.h
+++ b/src/core/hle/service/ns/ns.h
@@ -78,6 +78,9 @@ class IReadOnlyApplicationControlDataInterface final
public:
explicit IReadOnlyApplicationControlDataInterface(Core::System& system_);
~IReadOnlyApplicationControlDataInterface() override;
+
+private:
+ void GetApplicationControlData(Kernel::HLERequestContext& ctx);
};
class NS final : public ServiceFramework<NS> {
diff --git a/src/core/hle/service/nvdrv/core/container.cpp b/src/core/hle/service/nvdrv/core/container.cpp
new file mode 100644
index 000000000..37ca24f5d
--- /dev/null
+++ b/src/core/hle/service/nvdrv/core/container.cpp
@@ -0,0 +1,50 @@
+// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2022 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "core/hle/service/nvdrv/core/container.h"
+#include "core/hle/service/nvdrv/core/nvmap.h"
+#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
+#include "video_core/host1x/host1x.h"
+
+namespace Service::Nvidia::NvCore {
+
+struct ContainerImpl {
+ explicit ContainerImpl(Tegra::Host1x::Host1x& host1x_)
+ : file{host1x_}, manager{host1x_}, device_file_data{} {}
+ NvMap file;
+ SyncpointManager manager;
+ Container::Host1xDeviceFileData device_file_data;
+};
+
+Container::Container(Tegra::Host1x::Host1x& host1x_) {
+ impl = std::make_unique<ContainerImpl>(host1x_);
+}
+
+Container::~Container() = default;
+
+NvMap& Container::GetNvMapFile() {
+ return impl->file;
+}
+
+const NvMap& Container::GetNvMapFile() const {
+ return impl->file;
+}
+
+Container::Host1xDeviceFileData& Container::Host1xDeviceFile() {
+ return impl->device_file_data;
+}
+
+const Container::Host1xDeviceFileData& Container::Host1xDeviceFile() const {
+ return impl->device_file_data;
+}
+
+SyncpointManager& Container::GetSyncpointManager() {
+ return impl->manager;
+}
+
+const SyncpointManager& Container::GetSyncpointManager() const {
+ return impl->manager;
+}
+
+} // namespace Service::Nvidia::NvCore
diff --git a/src/core/hle/service/nvdrv/core/container.h b/src/core/hle/service/nvdrv/core/container.h
new file mode 100644
index 000000000..b4b63ac90
--- /dev/null
+++ b/src/core/hle/service/nvdrv/core/container.h
@@ -0,0 +1,52 @@
+// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2022 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <deque>
+#include <memory>
+#include <unordered_map>
+
+#include "core/hle/service/nvdrv/nvdata.h"
+
+namespace Tegra::Host1x {
+class Host1x;
+} // namespace Tegra::Host1x
+
+namespace Service::Nvidia::NvCore {
+
+class NvMap;
+class SyncpointManager;
+
+struct ContainerImpl;
+
+class Container {
+public:
+ explicit Container(Tegra::Host1x::Host1x& host1x);
+ ~Container();
+
+ NvMap& GetNvMapFile();
+
+ const NvMap& GetNvMapFile() const;
+
+ SyncpointManager& GetSyncpointManager();
+
+ const SyncpointManager& GetSyncpointManager() const;
+
+ struct Host1xDeviceFileData {
+ std::unordered_map<DeviceFD, u32> fd_to_id{};
+ std::deque<u32> syncpts_accumulated{};
+ u32 nvdec_next_id{};
+ u32 vic_next_id{};
+ };
+
+ Host1xDeviceFileData& Host1xDeviceFile();
+
+ const Host1xDeviceFileData& Host1xDeviceFile() const;
+
+private:
+ std::unique_ptr<ContainerImpl> impl;
+};
+
+} // namespace Service::Nvidia::NvCore
diff --git a/src/core/hle/service/nvdrv/core/nvmap.cpp b/src/core/hle/service/nvdrv/core/nvmap.cpp
new file mode 100644
index 000000000..a51ca5444
--- /dev/null
+++ b/src/core/hle/service/nvdrv/core/nvmap.cpp
@@ -0,0 +1,273 @@
+// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2022 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "common/alignment.h"
+#include "common/assert.h"
+#include "common/logging/log.h"
+#include "core/hle/service/nvdrv/core/nvmap.h"
+#include "core/memory.h"
+#include "video_core/host1x/host1x.h"
+
+using Core::Memory::YUZU_PAGESIZE;
+
+namespace Service::Nvidia::NvCore {
+NvMap::Handle::Handle(u64 size_, Id id_)
+ : size(size_), aligned_size(size), orig_size(size), id(id_) {
+ flags.raw = 0;
+}
+
+NvResult NvMap::Handle::Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress) {
+ std::scoped_lock lock(mutex);
+
+ // Handles cannot be allocated twice
+ if (allocated) {
+ return NvResult::AccessDenied;
+ }
+
+ flags = pFlags;
+ kind = pKind;
+ align = pAlign < YUZU_PAGESIZE ? YUZU_PAGESIZE : pAlign;
+
+ // This flag is only applicable for handles with an address passed
+ if (pAddress) {
+ flags.keep_uncached_after_free.Assign(0);
+ } else {
+ LOG_CRITICAL(Service_NVDRV,
+ "Mapping nvmap handles without a CPU side address is unimplemented!");
+ }
+
+ size = Common::AlignUp(size, YUZU_PAGESIZE);
+ aligned_size = Common::AlignUp(size, align);
+ address = pAddress;
+ allocated = true;
+
+ return NvResult::Success;
+}
+
+NvResult NvMap::Handle::Duplicate(bool internal_session) {
+ std::scoped_lock lock(mutex);
+ // Unallocated handles cannot be duplicated as duplication requires memory accounting (in HOS)
+ if (!allocated) [[unlikely]] {
+ return NvResult::BadValue;
+ }
+
+ // If we internally use FromId the duplication tracking of handles won't work accurately due to
+ // us not implementing per-process handle refs.
+ if (internal_session) {
+ internal_dupes++;
+ } else {
+ dupes++;
+ }
+
+ return NvResult::Success;
+}
+
+NvMap::NvMap(Tegra::Host1x::Host1x& host1x_) : host1x{host1x_} {}
+
+void NvMap::AddHandle(std::shared_ptr<Handle> handle_description) {
+ std::scoped_lock lock(handles_lock);
+
+ handles.emplace(handle_description->id, std::move(handle_description));
+}
+
+void NvMap::UnmapHandle(Handle& handle_description) {
+ // Remove pending unmap queue entry if needed
+ if (handle_description.unmap_queue_entry) {
+ unmap_queue.erase(*handle_description.unmap_queue_entry);
+ handle_description.unmap_queue_entry.reset();
+ }
+
+ // Free and unmap the handle from the SMMU
+ host1x.MemoryManager().Unmap(static_cast<GPUVAddr>(handle_description.pin_virt_address),
+ handle_description.aligned_size);
+ host1x.Allocator().Free(handle_description.pin_virt_address,
+ static_cast<u32>(handle_description.aligned_size));
+ handle_description.pin_virt_address = 0;
+}
+
+bool NvMap::TryRemoveHandle(const Handle& handle_description) {
+ // No dupes left, we can remove from handle map
+ if (handle_description.dupes == 0 && handle_description.internal_dupes == 0) {
+ std::scoped_lock lock(handles_lock);
+
+ auto it{handles.find(handle_description.id)};
+ if (it != handles.end()) {
+ handles.erase(it);
+ }
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
+NvResult NvMap::CreateHandle(u64 size, std::shared_ptr<NvMap::Handle>& result_out) {
+ if (!size) [[unlikely]] {
+ return NvResult::BadValue;
+ }
+
+ u32 id{next_handle_id.fetch_add(HandleIdIncrement, std::memory_order_relaxed)};
+ auto handle_description{std::make_shared<Handle>(size, id)};
+ AddHandle(handle_description);
+
+ result_out = handle_description;
+ return NvResult::Success;
+}
+
+std::shared_ptr<NvMap::Handle> NvMap::GetHandle(Handle::Id handle) {
+ std::scoped_lock lock(handles_lock);
+ try {
+ return handles.at(handle);
+ } catch (std::out_of_range&) {
+ return nullptr;
+ }
+}
+
+VAddr NvMap::GetHandleAddress(Handle::Id handle) {
+ std::scoped_lock lock(handles_lock);
+ try {
+ return handles.at(handle)->address;
+ } catch (std::out_of_range&) {
+ return 0;
+ }
+}
+
+u32 NvMap::PinHandle(NvMap::Handle::Id handle) {
+ auto handle_description{GetHandle(handle)};
+ if (!handle_description) [[unlikely]] {
+ return 0;
+ }
+
+ std::scoped_lock lock(handle_description->mutex);
+ if (!handle_description->pins) {
+ // If we're in the unmap queue we can just remove ourselves and return since we're already
+ // mapped
+ {
+ // Lock now to prevent our queue entry from being removed for allocation in-between the
+ // following check and erase
+ std::scoped_lock queueLock(unmap_queue_lock);
+ if (handle_description->unmap_queue_entry) {
+ unmap_queue.erase(*handle_description->unmap_queue_entry);
+ handle_description->unmap_queue_entry.reset();
+
+ handle_description->pins++;
+ return handle_description->pin_virt_address;
+ }
+ }
+
+ // If not then allocate some space and map it
+ u32 address{};
+ auto& smmu_allocator = host1x.Allocator();
+ auto& smmu_memory_manager = host1x.MemoryManager();
+ while (!(address =
+ smmu_allocator.Allocate(static_cast<u32>(handle_description->aligned_size)))) {
+ // Free handles until the allocation succeeds
+ std::scoped_lock queueLock(unmap_queue_lock);
+ if (auto freeHandleDesc{unmap_queue.front()}) {
+ // Handles in the unmap queue are guaranteed not to be pinned so don't bother
+ // checking if they are before unmapping
+ std::scoped_lock freeLock(freeHandleDesc->mutex);
+ if (handle_description->pin_virt_address)
+ UnmapHandle(*freeHandleDesc);
+ } else {
+ LOG_CRITICAL(Service_NVDRV, "Ran out of SMMU address space!");
+ }
+ }
+
+ smmu_memory_manager.Map(static_cast<GPUVAddr>(address), handle_description->address,
+ handle_description->aligned_size);
+ handle_description->pin_virt_address = address;
+ }
+
+ handle_description->pins++;
+ return handle_description->pin_virt_address;
+}
+
+void NvMap::UnpinHandle(Handle::Id handle) {
+ auto handle_description{GetHandle(handle)};
+ if (!handle_description) {
+ return;
+ }
+
+ std::scoped_lock lock(handle_description->mutex);
+ if (--handle_description->pins < 0) {
+ LOG_WARNING(Service_NVDRV, "Pin count imbalance detected!");
+ } else if (!handle_description->pins) {
+ std::scoped_lock queueLock(unmap_queue_lock);
+
+ // Add to the unmap queue allowing this handle's memory to be freed if needed
+ unmap_queue.push_back(handle_description);
+ handle_description->unmap_queue_entry = std::prev(unmap_queue.end());
+ }
+}
+
+void NvMap::DuplicateHandle(Handle::Id handle, bool internal_session) {
+ auto handle_description{GetHandle(handle)};
+ if (!handle_description) {
+ LOG_CRITICAL(Service_NVDRV, "Unregistered handle!");
+ return;
+ }
+
+ auto result = handle_description->Duplicate(internal_session);
+ if (result != NvResult::Success) {
+ LOG_CRITICAL(Service_NVDRV, "Could not duplicate handle!");
+ }
+}
+
+std::optional<NvMap::FreeInfo> NvMap::FreeHandle(Handle::Id handle, bool internal_session) {
+ std::weak_ptr<Handle> hWeak{GetHandle(handle)};
+ FreeInfo freeInfo;
+
+ // We use a weak ptr here so we can tell when the handle has been freed and report that back to
+ // guest
+ if (auto handle_description = hWeak.lock()) {
+ std::scoped_lock lock(handle_description->mutex);
+
+ if (internal_session) {
+ if (--handle_description->internal_dupes < 0)
+ LOG_WARNING(Service_NVDRV, "Internal duplicate count imbalance detected!");
+ } else {
+ if (--handle_description->dupes < 0) {
+ LOG_WARNING(Service_NVDRV, "User duplicate count imbalance detected!");
+ } else if (handle_description->dupes == 0) {
+ // Force unmap the handle
+ if (handle_description->pin_virt_address) {
+ std::scoped_lock queueLock(unmap_queue_lock);
+ UnmapHandle(*handle_description);
+ }
+
+ handle_description->pins = 0;
+ }
+ }
+
+ // Try to remove the shared ptr to the handle from the map, if nothing else is using the
+ // handle then it will now be freed when `handle_description` goes out of scope
+ if (TryRemoveHandle(*handle_description)) {
+ LOG_DEBUG(Service_NVDRV, "Removed nvmap handle: {}", handle);
+ } else {
+ LOG_DEBUG(Service_NVDRV,
+ "Tried to free nvmap handle: {} but didn't as it still has duplicates",
+ handle);
+ }
+
+ freeInfo = {
+ .address = handle_description->address,
+ .size = handle_description->size,
+ .was_uncached = handle_description->flags.map_uncached.Value() != 0,
+ .can_unlock = true,
+ };
+ } else {
+ return std::nullopt;
+ }
+
+ // If the handle hasn't been freed from memory, mark that
+ if (!hWeak.expired()) {
+ LOG_DEBUG(Service_NVDRV, "nvmap handle: {} wasn't freed as it is still in use", handle);
+ freeInfo.can_unlock = false;
+ }
+
+ return freeInfo;
+}
+
+} // namespace Service::Nvidia::NvCore
diff --git a/src/core/hle/service/nvdrv/core/nvmap.h b/src/core/hle/service/nvdrv/core/nvmap.h
new file mode 100644
index 000000000..a8e573890
--- /dev/null
+++ b/src/core/hle/service/nvdrv/core/nvmap.h
@@ -0,0 +1,176 @@
+// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2022 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <atomic>
+#include <list>
+#include <memory>
+#include <mutex>
+#include <optional>
+#include <unordered_map>
+#include <assert.h>
+
+#include "common/bit_field.h"
+#include "common/common_types.h"
+#include "core/hle/service/nvdrv/nvdata.h"
+
+namespace Tegra {
+
+namespace Host1x {
+class Host1x;
+} // namespace Host1x
+
+} // namespace Tegra
+
+namespace Service::Nvidia::NvCore {
+/**
+ * @brief The nvmap core class holds the global state for nvmap and provides methods to manage
+ * handles
+ */
+class NvMap {
+public:
+ /**
+ * @brief A handle to a contiguous block of memory in an application's address space
+ */
+ struct Handle {
+ std::mutex mutex;
+
+ u64 align{}; //!< The alignment to use when pinning the handle onto the SMMU
+ u64 size; //!< Page-aligned size of the memory the handle refers to
+ u64 aligned_size; //!< `align`-aligned size of the memory the handle refers to
+ u64 orig_size; //!< Original unaligned size of the memory this handle refers to
+
+ s32 dupes{1}; //!< How many guest references there are to this handle
+ s32 internal_dupes{0}; //!< How many emulator-internal references there are to this handle
+
+ using Id = u32;
+ Id id; //!< A globally unique identifier for this handle
+
+ s32 pins{};
+ u32 pin_virt_address{};
+ std::optional<typename std::list<std::shared_ptr<Handle>>::iterator> unmap_queue_entry{};
+
+ union Flags {
+ u32 raw;
+ BitField<0, 1, u32> map_uncached; //!< If the handle should be mapped as uncached
+ BitField<2, 1, u32> keep_uncached_after_free; //!< Only applicable when the handle was
+ //!< allocated with a fixed address
+ BitField<4, 1, u32> _unk0_; //!< Passed to IOVMM for pins
+ } flags{};
+ static_assert(sizeof(Flags) == sizeof(u32));
+
+ u64 address{}; //!< The memory location in the guest's AS that this handle corresponds to,
+ //!< this can also be in the nvdrv tmem
+ bool is_shared_mem_mapped{}; //!< If this nvmap has been mapped with the MapSharedMem IPC
+ //!< call
+
+ u8 kind{}; //!< Used for memory compression
+ bool allocated{}; //!< If the handle has been allocated with `Alloc`
+
+ u64 dma_map_addr{}; //! remove me after implementing pinning.
+
+ Handle(u64 size, Id id);
+
+ /**
+ * @brief Sets up the handle with the given memory config, can allocate memory from the tmem
+ * if a 0 address is passed
+ */
+ [[nodiscard]] NvResult Alloc(Flags pFlags, u32 pAlign, u8 pKind, u64 pAddress);
+
+ /**
+ * @brief Increases the dupe counter of the handle for the given session
+ */
+ [[nodiscard]] NvResult Duplicate(bool internal_session);
+
+ /**
+ * @brief Obtains a pointer to the handle's memory and marks the handle it as having been
+ * mapped
+ */
+ u8* GetPointer() {
+ if (!address) {
+ return nullptr;
+ }
+
+ is_shared_mem_mapped = true;
+ return reinterpret_cast<u8*>(address);
+ }
+ };
+
+ /**
+ * @brief Encapsulates the result of a FreeHandle operation
+ */
+ struct FreeInfo {
+ u64 address; //!< Address the handle referred to before deletion
+ u64 size; //!< Page-aligned handle size
+ bool was_uncached; //!< If the handle was allocated as uncached
+ bool can_unlock; //!< If the address region is ready to be unlocked
+ };
+
+ explicit NvMap(Tegra::Host1x::Host1x& host1x);
+
+ /**
+ * @brief Creates an unallocated handle of the given size
+ */
+ [[nodiscard]] NvResult CreateHandle(u64 size, std::shared_ptr<NvMap::Handle>& result_out);
+
+ std::shared_ptr<Handle> GetHandle(Handle::Id handle);
+
+ VAddr GetHandleAddress(Handle::Id handle);
+
+ /**
+ * @brief Maps a handle into the SMMU address space
+ * @note This operation is refcounted, the number of calls to this must eventually match the
+ * number of calls to `UnpinHandle`
+ * @return The SMMU virtual address that the handle has been mapped to
+ */
+ u32 PinHandle(Handle::Id handle);
+
+ /**
+ * @brief When this has been called an equal number of times to `PinHandle` for the supplied
+ * handle it will be added to a list of handles to be freed when necessary
+ */
+ void UnpinHandle(Handle::Id handle);
+
+ /**
+ * @brief Tries to duplicate a handle
+ */
+ void DuplicateHandle(Handle::Id handle, bool internal_session = false);
+
+ /**
+ * @brief Tries to free a handle and remove a single dupe
+ * @note If a handle has no dupes left and has no other users a FreeInfo struct will be returned
+ * describing the prior state of the handle
+ */
+ std::optional<FreeInfo> FreeHandle(Handle::Id handle, bool internal_session);
+
+private:
+ std::list<std::shared_ptr<Handle>> unmap_queue{};
+ std::mutex unmap_queue_lock{}; //!< Protects access to `unmap_queue`
+
+ std::unordered_map<Handle::Id, std::shared_ptr<Handle>>
+ handles{}; //!< Main owning map of handles
+ std::mutex handles_lock; //!< Protects access to `handles`
+
+ static constexpr u32 HandleIdIncrement{
+ 4}; //!< Each new handle ID is an increment of 4 from the previous
+ std::atomic<u32> next_handle_id{HandleIdIncrement};
+ Tegra::Host1x::Host1x& host1x;
+
+ void AddHandle(std::shared_ptr<Handle> handle);
+
+ /**
+ * @brief Unmaps and frees the SMMU memory region a handle is mapped to
+ * @note Both `unmap_queue_lock` and `handle_description.mutex` MUST be locked when calling this
+ */
+ void UnmapHandle(Handle& handle_description);
+
+ /**
+ * @brief Removes a handle from the map taking its dupes into account
+ * @note handle_description.mutex MUST be locked when calling this
+ * @return If the handle was removed from the map
+ */
+ bool TryRemoveHandle(const Handle& handle_description);
+};
+} // namespace Service::Nvidia::NvCore
diff --git a/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp b/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp
new file mode 100644
index 000000000..eda2041a0
--- /dev/null
+++ b/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp
@@ -0,0 +1,121 @@
+// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2022 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "common/assert.h"
+#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
+#include "video_core/host1x/host1x.h"
+
+namespace Service::Nvidia::NvCore {
+
+SyncpointManager::SyncpointManager(Tegra::Host1x::Host1x& host1x_) : host1x{host1x_} {
+ constexpr u32 VBlank0SyncpointId{26};
+ constexpr u32 VBlank1SyncpointId{27};
+
+ // Reserve both vblank syncpoints as client managed as they use Continuous Mode
+ // Refer to section 14.3.5.3 of the TRM for more information on Continuous Mode
+ // https://github.com/Jetson-TX1-AndroidTV/android_kernel_jetson_tx1_hdmi_primary/blob/8f74a72394efb871cb3f886a3de2998cd7ff2990/drivers/gpu/host1x/drm/dc.c#L660
+ ReserveSyncpoint(VBlank0SyncpointId, true);
+ ReserveSyncpoint(VBlank1SyncpointId, true);
+
+ for (u32 syncpoint_id : channel_syncpoints) {
+ if (syncpoint_id) {
+ ReserveSyncpoint(syncpoint_id, false);
+ }
+ }
+}
+
+SyncpointManager::~SyncpointManager() = default;
+
+u32 SyncpointManager::ReserveSyncpoint(u32 id, bool client_managed) {
+ if (syncpoints.at(id).reserved) {
+ ASSERT_MSG(false, "Requested syncpoint is in use");
+ return 0;
+ }
+
+ syncpoints.at(id).reserved = true;
+ syncpoints.at(id).interface_managed = client_managed;
+
+ return id;
+}
+
+u32 SyncpointManager::FindFreeSyncpoint() {
+ for (u32 i{1}; i < syncpoints.size(); i++) {
+ if (!syncpoints[i].reserved) {
+ return i;
+ }
+ }
+ ASSERT_MSG(false, "Failed to find a free syncpoint!");
+ return 0;
+}
+
+u32 SyncpointManager::AllocateSyncpoint(bool client_managed) {
+ std::lock_guard lock(reservation_lock);
+ return ReserveSyncpoint(FindFreeSyncpoint(), client_managed);
+}
+
+void SyncpointManager::FreeSyncpoint(u32 id) {
+ std::lock_guard lock(reservation_lock);
+ ASSERT(syncpoints.at(id).reserved);
+ syncpoints.at(id).reserved = false;
+}
+
+bool SyncpointManager::IsSyncpointAllocated(u32 id) {
+ return (id <= SyncpointCount) && syncpoints[id].reserved;
+}
+
+bool SyncpointManager::HasSyncpointExpired(u32 id, u32 threshold) const {
+ const SyncpointInfo& syncpoint{syncpoints.at(id)};
+
+ if (!syncpoint.reserved) {
+ ASSERT(false);
+ return 0;
+ }
+
+ // If the interface manages counters then we don't keep track of the maximum value as it handles
+ // sanity checking the values then
+ if (syncpoint.interface_managed) {
+ return static_cast<s32>(syncpoint.counter_min - threshold) >= 0;
+ } else {
+ return (syncpoint.counter_max - threshold) >= (syncpoint.counter_min - threshold);
+ }
+}
+
+u32 SyncpointManager::IncrementSyncpointMaxExt(u32 id, u32 amount) {
+ if (!syncpoints.at(id).reserved) {
+ ASSERT(false);
+ return 0;
+ }
+
+ return syncpoints.at(id).counter_max += amount;
+}
+
+u32 SyncpointManager::ReadSyncpointMinValue(u32 id) {
+ if (!syncpoints.at(id).reserved) {
+ ASSERT(false);
+ return 0;
+ }
+
+ return syncpoints.at(id).counter_min;
+}
+
+u32 SyncpointManager::UpdateMin(u32 id) {
+ if (!syncpoints.at(id).reserved) {
+ ASSERT(false);
+ return 0;
+ }
+
+ syncpoints.at(id).counter_min = host1x.GetSyncpointManager().GetHostSyncpointValue(id);
+ return syncpoints.at(id).counter_min;
+}
+
+NvFence SyncpointManager::GetSyncpointFence(u32 id) {
+ if (!syncpoints.at(id).reserved) {
+ ASSERT(false);
+ return NvFence{};
+ }
+
+ return {.id = static_cast<s32>(id), .value = syncpoints.at(id).counter_max};
+}
+
+} // namespace Service::Nvidia::NvCore
diff --git a/src/core/hle/service/nvdrv/core/syncpoint_manager.h b/src/core/hle/service/nvdrv/core/syncpoint_manager.h
new file mode 100644
index 000000000..b76ef9032
--- /dev/null
+++ b/src/core/hle/service/nvdrv/core/syncpoint_manager.h
@@ -0,0 +1,134 @@
+// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2022 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <array>
+#include <atomic>
+#include <mutex>
+
+#include "common/common_types.h"
+#include "core/hle/service/nvdrv/nvdata.h"
+
+namespace Tegra::Host1x {
+class Host1x;
+} // namespace Tegra::Host1x
+
+namespace Service::Nvidia::NvCore {
+
+enum class ChannelType : u32 {
+ MsEnc = 0,
+ VIC = 1,
+ GPU = 2,
+ NvDec = 3,
+ Display = 4,
+ NvJpg = 5,
+ TSec = 6,
+ Max = 7
+};
+
+/**
+ * @brief SyncpointManager handles allocating and accessing host1x syncpoints, these are cached
+ * versions of the HW syncpoints which are intermittently synced
+ * @note Refer to Chapter 14 of the Tegra X1 TRM for an exhaustive overview of them
+ * @url https://http.download.nvidia.com/tegra-public-appnotes/host1x.html
+ * @url
+ * https://github.com/Jetson-TX1-AndroidTV/android_kernel_jetson_tx1_hdmi_primary/blob/jetson-tx1/drivers/video/tegra/host/nvhost_syncpt.c
+ */
+class SyncpointManager final {
+public:
+ explicit SyncpointManager(Tegra::Host1x::Host1x& host1x);
+ ~SyncpointManager();
+
+ /**
+ * @brief Checks if the given syncpoint is both allocated and below the number of HW syncpoints
+ */
+ bool IsSyncpointAllocated(u32 id);
+
+ /**
+ * @brief Finds a free syncpoint and reserves it
+ * @return The ID of the reserved syncpoint
+ */
+ u32 AllocateSyncpoint(bool client_managed);
+
+ /**
+ * @url
+ * https://github.com/Jetson-TX1-AndroidTV/android_kernel_jetson_tx1_hdmi_primary/blob/8f74a72394efb871cb3f886a3de2998cd7ff2990/drivers/gpu/host1x/syncpt.c#L259
+ */
+ bool HasSyncpointExpired(u32 id, u32 threshold) const;
+
+ bool IsFenceSignalled(NvFence fence) const {
+ return HasSyncpointExpired(fence.id, fence.value);
+ }
+
+ /**
+ * @brief Atomically increments the maximum value of a syncpoint by the given amount
+ * @return The new max value of the syncpoint
+ */
+ u32 IncrementSyncpointMaxExt(u32 id, u32 amount);
+
+ /**
+ * @return The minimum value of the syncpoint
+ */
+ u32 ReadSyncpointMinValue(u32 id);
+
+ /**
+ * @brief Synchronises the minimum value of the syncpoint to with the GPU
+ * @return The new minimum value of the syncpoint
+ */
+ u32 UpdateMin(u32 id);
+
+ /**
+ * @brief Frees the usage of a syncpoint.
+ */
+ void FreeSyncpoint(u32 id);
+
+ /**
+ * @return A fence that will be signalled once this syncpoint hits its maximum value
+ */
+ NvFence GetSyncpointFence(u32 id);
+
+ static constexpr std::array<u32, static_cast<u32>(ChannelType::Max)> channel_syncpoints{
+ 0x0, // `MsEnc` is unimplemented
+ 0xC, // `VIC`
+ 0x0, // `GPU` syncpoints are allocated per-channel instead
+ 0x36, // `NvDec`
+ 0x0, // `Display` is unimplemented
+ 0x37, // `NvJpg`
+ 0x0, // `TSec` is unimplemented
+ }; //!< Maps each channel ID to a constant syncpoint
+
+private:
+ /**
+ * @note reservation_lock should be locked when calling this
+ */
+ u32 ReserveSyncpoint(u32 id, bool client_managed);
+
+ /**
+ * @return The ID of the first free syncpoint
+ */
+ u32 FindFreeSyncpoint();
+
+ struct SyncpointInfo {
+ std::atomic<u32> counter_min; //!< The least value the syncpoint can be (The value it was
+ //!< when it was last synchronized with host1x)
+ std::atomic<u32> counter_max; //!< The maximum value the syncpoint can reach according to
+ //!< the current usage
+ bool interface_managed; //!< If the syncpoint is managed by a host1x client interface, a
+ //!< client interface is a HW block that can handle host1x
+ //!< transactions on behalf of a host1x client (Which would
+ //!< otherwise need to be manually synced using PIO which is
+ //!< synchronous and requires direct cooperation of the CPU)
+ bool reserved; //!< If the syncpoint is reserved or not, not to be confused with a reserved
+ //!< value
+ };
+
+ constexpr static std::size_t SyncpointCount{192};
+ std::array<SyncpointInfo, SyncpointCount> syncpoints{};
+ std::mutex reservation_lock;
+
+ Tegra::Host1x::Host1x& host1x;
+};
+
+} // namespace Service::Nvidia::NvCore
diff --git a/src/core/hle/service/nvdrv/devices/nvdevice.h b/src/core/hle/service/nvdrv/devices/nvdevice.h
index 696e8121e..204b0e757 100644
--- a/src/core/hle/service/nvdrv/devices/nvdevice.h
+++ b/src/core/hle/service/nvdrv/devices/nvdevice.h
@@ -11,6 +11,10 @@ namespace Core {
class System;
}
+namespace Kernel {
+class KEvent;
+}
+
namespace Service::Nvidia::Devices {
/// Represents an abstract nvidia device node. It is to be subclassed by concrete device nodes to
@@ -64,6 +68,10 @@ public:
*/
virtual void OnClose(DeviceFD fd) = 0;
+ virtual Kernel::KEvent* QueryEvent(u32 event_id) {
+ return nullptr;
+ }
+
protected:
Core::System& system;
};
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index 604711914..4122fc98d 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -5,15 +5,16 @@
#include "common/logging/log.h"
#include "core/core.h"
#include "core/core_timing.h"
+#include "core/hle/service/nvdrv/core/container.h"
+#include "core/hle/service/nvdrv/core/nvmap.h"
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
-#include "core/hle/service/nvdrv/devices/nvmap.h"
#include "core/perf_stats.h"
#include "video_core/gpu.h"
namespace Service::Nvidia::Devices {
-nvdisp_disp0::nvdisp_disp0(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_)
- : nvdevice{system_}, nvmap_dev{std::move(nvmap_dev_)} {}
+nvdisp_disp0::nvdisp_disp0(Core::System& system_, NvCore::Container& core)
+ : nvdevice{system_}, container{core}, nvmap{core.GetNvMapFile()} {}
nvdisp_disp0::~nvdisp_disp0() = default;
NvResult nvdisp_disp0::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
@@ -39,8 +40,9 @@ void nvdisp_disp0::OnClose(DeviceFD fd) {}
void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, android::PixelFormat format, u32 width,
u32 height, u32 stride, android::BufferTransformFlags transform,
- const Common::Rectangle<int>& crop_rect) {
- const VAddr addr = nvmap_dev->GetObjectAddress(buffer_handle);
+ const Common::Rectangle<int>& crop_rect,
+ std::array<Service::Nvidia::NvFence, 4>& fences, u32 num_fences) {
+ const VAddr addr = nvmap.GetHandleAddress(buffer_handle);
LOG_TRACE(Service,
"Drawing from address {:X} offset {:08X} Width {} Height {} Stride {} Format {}",
addr, offset, width, height, stride, format);
@@ -48,10 +50,15 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, android::PixelFormat form
const Tegra::FramebufferConfig framebuffer{addr, offset, width, height,
stride, format, transform, crop_rect};
+ system.GPU().RequestSwapBuffers(&framebuffer, fences, num_fences);
system.GetPerfStats().EndSystemFrame();
- system.GPU().SwapBuffers(&framebuffer);
system.SpeedLimiter().DoSpeedLimiting(system.CoreTiming().GetGlobalTimeUs());
system.GetPerfStats().BeginSystemFrame();
}
+Kernel::KEvent* nvdisp_disp0::QueryEvent(u32 event_id) {
+ LOG_CRITICAL(Service_NVDRV, "Unknown DISP Event {}", event_id);
+ return nullptr;
+}
+
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
index 67b105e02..04217ab12 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.h
@@ -11,13 +11,18 @@
#include "core/hle/service/nvflinger/buffer_transform_flags.h"
#include "core/hle/service/nvflinger/pixel_format.h"
+namespace Service::Nvidia::NvCore {
+class Container;
+class NvMap;
+} // namespace Service::Nvidia::NvCore
+
namespace Service::Nvidia::Devices {
class nvmap;
class nvdisp_disp0 final : public nvdevice {
public:
- explicit nvdisp_disp0(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_);
+ explicit nvdisp_disp0(Core::System& system_, NvCore::Container& core);
~nvdisp_disp0() override;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
@@ -33,10 +38,14 @@ public:
/// Performs a screen flip, drawing the buffer pointed to by the handle.
void flip(u32 buffer_handle, u32 offset, android::PixelFormat format, u32 width, u32 height,
u32 stride, android::BufferTransformFlags transform,
- const Common::Rectangle<int>& crop_rect);
+ const Common::Rectangle<int>& crop_rect,
+ std::array<Service::Nvidia::NvFence, 4>& fences, u32 num_fences);
+
+ Kernel::KEvent* QueryEvent(u32 event_id) override;
private:
- std::shared_ptr<nvmap> nvmap_dev;
+ NvCore::Container& container;
+ NvCore::NvMap& nvmap;
};
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
index 9867a648d..b635e6ed1 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.cpp
@@ -1,21 +1,30 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
#include <cstring>
#include <utility>
+#include "common/alignment.h"
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
+#include "core/hle/service/nvdrv/core/container.h"
+#include "core/hle/service/nvdrv/core/nvmap.h"
#include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h"
-#include "core/hle/service/nvdrv/devices/nvmap.h"
+#include "core/hle/service/nvdrv/devices/nvhost_gpu.h"
+#include "core/hle/service/nvdrv/nvdrv.h"
+#include "video_core/control/channel_state.h"
+#include "video_core/gpu.h"
#include "video_core/memory_manager.h"
#include "video_core/rasterizer_interface.h"
namespace Service::Nvidia::Devices {
-nvhost_as_gpu::nvhost_as_gpu(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_)
- : nvdevice{system_}, nvmap_dev{std::move(nvmap_dev_)} {}
+nvhost_as_gpu::nvhost_as_gpu(Core::System& system_, Module& module_, NvCore::Container& core)
+ : nvdevice{system_}, module{module_}, container{core}, nvmap{core.GetNvMapFile()}, vm{},
+ gmmu{} {}
+
nvhost_as_gpu::~nvhost_as_gpu() = default;
NvResult nvhost_as_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
@@ -82,12 +91,52 @@ NvResult nvhost_as_gpu::AllocAsEx(const std::vector<u8>& input, std::vector<u8>&
IoctlAllocAsEx params{};
std::memcpy(&params, input.data(), input.size());
- LOG_WARNING(Service_NVDRV, "(STUBBED) called, big_page_size=0x{:X}", params.big_page_size);
- if (params.big_page_size == 0) {
- params.big_page_size = DEFAULT_BIG_PAGE_SIZE;
+ LOG_DEBUG(Service_NVDRV, "called, big_page_size=0x{:X}", params.big_page_size);
+
+ std::scoped_lock lock(mutex);
+
+ if (vm.initialised) {
+ ASSERT_MSG(false, "Cannot initialise an address space twice!");
+ return NvResult::InvalidState;
+ }
+
+ if (params.big_page_size) {
+ if (!std::has_single_bit(params.big_page_size)) {
+ LOG_ERROR(Service_NVDRV, "Non power-of-2 big page size: 0x{:X}!", params.big_page_size);
+ return NvResult::BadValue;
+ }
+
+ if ((params.big_page_size & VM::SUPPORTED_BIG_PAGE_SIZES) == 0) {
+ LOG_ERROR(Service_NVDRV, "Unsupported big page size: 0x{:X}!", params.big_page_size);
+ return NvResult::BadValue;
+ }
+
+ vm.big_page_size = params.big_page_size;
+ vm.big_page_size_bits = static_cast<u32>(std::countr_zero(params.big_page_size));
+
+ vm.va_range_start = params.big_page_size << VM::VA_START_SHIFT;
+ }
+
+ // If this is unspecified then default values should be used
+ if (params.va_range_start) {
+ vm.va_range_start = params.va_range_start;
+ vm.va_range_split = params.va_range_split;
+ vm.va_range_end = params.va_range_end;
}
- big_page_size = params.big_page_size;
+ const auto start_pages{static_cast<u32>(vm.va_range_start >> VM::PAGE_SIZE_BITS)};
+ const auto end_pages{static_cast<u32>(vm.va_range_split >> VM::PAGE_SIZE_BITS)};
+ vm.small_page_allocator = std::make_shared<VM::Allocator>(start_pages, end_pages);
+
+ const auto start_big_pages{static_cast<u32>(vm.va_range_split >> vm.big_page_size_bits)};
+ const auto end_big_pages{
+ static_cast<u32>((vm.va_range_end - vm.va_range_split) >> vm.big_page_size_bits)};
+ vm.big_page_allocator = std::make_unique<VM::Allocator>(start_big_pages, end_big_pages);
+
+ gmmu = std::make_shared<Tegra::MemoryManager>(system, 40, vm.big_page_size_bits,
+ VM::PAGE_SIZE_BITS);
+ system.GPU().InitAddressSpace(*gmmu);
+ vm.initialised = true;
return NvResult::Success;
}
@@ -99,21 +148,76 @@ NvResult nvhost_as_gpu::AllocateSpace(const std::vector<u8>& input, std::vector<
LOG_DEBUG(Service_NVDRV, "called, pages={:X}, page_size={:X}, flags={:X}", params.pages,
params.page_size, params.flags);
- const auto size{static_cast<u64>(params.pages) * static_cast<u64>(params.page_size)};
- if ((params.flags & AddressSpaceFlags::FixedOffset) != AddressSpaceFlags::None) {
- params.offset = *system.GPU().MemoryManager().AllocateFixed(params.offset, size);
+ std::scoped_lock lock(mutex);
+
+ if (!vm.initialised) {
+ return NvResult::BadValue;
+ }
+
+ if (params.page_size != VM::YUZU_PAGESIZE && params.page_size != vm.big_page_size) {
+ return NvResult::BadValue;
+ }
+
+ if (params.page_size != vm.big_page_size &&
+ ((params.flags & MappingFlags::Sparse) != MappingFlags::None)) {
+ UNIMPLEMENTED_MSG("Sparse small pages are not implemented!");
+ return NvResult::NotImplemented;
+ }
+
+ const u32 page_size_bits{params.page_size == VM::YUZU_PAGESIZE ? VM::PAGE_SIZE_BITS
+ : vm.big_page_size_bits};
+
+ auto& allocator{params.page_size == VM::YUZU_PAGESIZE ? *vm.small_page_allocator
+ : *vm.big_page_allocator};
+
+ if ((params.flags & MappingFlags::Fixed) != MappingFlags::None) {
+ allocator.AllocateFixed(static_cast<u32>(params.offset >> page_size_bits), params.pages);
} else {
- params.offset = system.GPU().MemoryManager().Allocate(size, params.align);
+ params.offset = static_cast<u64>(allocator.Allocate(params.pages)) << page_size_bits;
+ if (!params.offset) {
+ ASSERT_MSG(false, "Failed to allocate free space in the GPU AS!");
+ return NvResult::InsufficientMemory;
+ }
}
- auto result = NvResult::Success;
- if (!params.offset) {
- LOG_CRITICAL(Service_NVDRV, "allocation failed for size {}", size);
- result = NvResult::InsufficientMemory;
+ u64 size{static_cast<u64>(params.pages) * params.page_size};
+
+ if ((params.flags & MappingFlags::Sparse) != MappingFlags::None) {
+ gmmu->MapSparse(params.offset, size);
}
+ allocation_map[params.offset] = {
+ .size = size,
+ .mappings{},
+ .page_size = params.page_size,
+ .sparse = (params.flags & MappingFlags::Sparse) != MappingFlags::None,
+ .big_pages = params.page_size != VM::YUZU_PAGESIZE,
+ };
+
std::memcpy(output.data(), &params, output.size());
- return result;
+ return NvResult::Success;
+}
+
+void nvhost_as_gpu::FreeMappingLocked(u64 offset) {
+ auto mapping{mapping_map.at(offset)};
+
+ if (!mapping->fixed) {
+ auto& allocator{mapping->big_page ? *vm.big_page_allocator : *vm.small_page_allocator};
+ u32 page_size_bits{mapping->big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS};
+
+ allocator.Free(static_cast<u32>(mapping->offset >> page_size_bits),
+ static_cast<u32>(mapping->size >> page_size_bits));
+ }
+
+ // Sparse mappings shouldn't be fully unmapped, just returned to their sparse state
+ // Only FreeSpace can unmap them fully
+ if (mapping->sparse_alloc) {
+ gmmu->MapSparse(offset, mapping->size, mapping->big_page);
+ } else {
+ gmmu->Unmap(offset, mapping->size);
+ }
+
+ mapping_map.erase(offset);
}
NvResult nvhost_as_gpu::FreeSpace(const std::vector<u8>& input, std::vector<u8>& output) {
@@ -123,8 +227,40 @@ NvResult nvhost_as_gpu::FreeSpace(const std::vector<u8>& input, std::vector<u8>&
LOG_DEBUG(Service_NVDRV, "called, offset={:X}, pages={:X}, page_size={:X}", params.offset,
params.pages, params.page_size);
- system.GPU().MemoryManager().Unmap(params.offset,
- static_cast<std::size_t>(params.pages) * params.page_size);
+ std::scoped_lock lock(mutex);
+
+ if (!vm.initialised) {
+ return NvResult::BadValue;
+ }
+
+ try {
+ auto allocation{allocation_map[params.offset]};
+
+ if (allocation.page_size != params.page_size ||
+ allocation.size != (static_cast<u64>(params.pages) * params.page_size)) {
+ return NvResult::BadValue;
+ }
+
+ for (const auto& mapping : allocation.mappings) {
+ FreeMappingLocked(mapping->offset);
+ }
+
+ // Unset sparse flag if required
+ if (allocation.sparse) {
+ gmmu->Unmap(params.offset, allocation.size);
+ }
+
+ auto& allocator{params.page_size == VM::YUZU_PAGESIZE ? *vm.small_page_allocator
+ : *vm.big_page_allocator};
+ u32 page_size_bits{params.page_size == VM::YUZU_PAGESIZE ? VM::PAGE_SIZE_BITS
+ : vm.big_page_size_bits};
+
+ allocator.Free(static_cast<u32>(params.offset >> page_size_bits),
+ static_cast<u32>(allocation.size >> page_size_bits));
+ allocation_map.erase(params.offset);
+ } catch (const std::out_of_range&) {
+ return NvResult::BadValue;
+ }
std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
@@ -135,35 +271,53 @@ NvResult nvhost_as_gpu::Remap(const std::vector<u8>& input, std::vector<u8>& out
LOG_DEBUG(Service_NVDRV, "called, num_entries=0x{:X}", num_entries);
- auto result = NvResult::Success;
std::vector<IoctlRemapEntry> entries(num_entries);
std::memcpy(entries.data(), input.data(), input.size());
+ std::scoped_lock lock(mutex);
+
+ if (!vm.initialised) {
+ return NvResult::BadValue;
+ }
+
for (const auto& entry : entries) {
- LOG_DEBUG(Service_NVDRV, "remap entry, offset=0x{:X} handle=0x{:X} pages=0x{:X}",
- entry.offset, entry.nvmap_handle, entry.pages);
+ GPUVAddr virtual_address{static_cast<u64>(entry.as_offset_big_pages)
+ << vm.big_page_size_bits};
+ u64 size{static_cast<u64>(entry.big_pages) << vm.big_page_size_bits};
- const auto object{nvmap_dev->GetObject(entry.nvmap_handle)};
- if (!object) {
- LOG_CRITICAL(Service_NVDRV, "invalid nvmap_handle={:X}", entry.nvmap_handle);
- result = NvResult::InvalidState;
- break;
+ auto alloc{allocation_map.upper_bound(virtual_address)};
+
+ if (alloc-- == allocation_map.begin() ||
+ (virtual_address - alloc->first) + size > alloc->second.size) {
+ LOG_WARNING(Service_NVDRV, "Cannot remap into an unallocated region!");
+ return NvResult::BadValue;
}
- const auto offset{static_cast<GPUVAddr>(entry.offset) << 0x10};
- const auto size{static_cast<u64>(entry.pages) << 0x10};
- const auto map_offset{static_cast<u64>(entry.map_offset) << 0x10};
- const auto addr{system.GPU().MemoryManager().Map(object->addr + map_offset, offset, size)};
+ if (!alloc->second.sparse) {
+ LOG_WARNING(Service_NVDRV, "Cannot remap a non-sparse mapping!");
+ return NvResult::BadValue;
+ }
- if (!addr) {
- LOG_CRITICAL(Service_NVDRV, "map returned an invalid address!");
- result = NvResult::InvalidState;
- break;
+ const bool use_big_pages = alloc->second.big_pages;
+ if (!entry.handle) {
+ gmmu->MapSparse(virtual_address, size, use_big_pages);
+ } else {
+ auto handle{nvmap.GetHandle(entry.handle)};
+ if (!handle) {
+ return NvResult::BadValue;
+ }
+
+ VAddr cpu_address{static_cast<VAddr>(
+ handle->address +
+ (static_cast<u64>(entry.handle_offset_big_pages) << vm.big_page_size_bits))};
+
+ gmmu->Map(virtual_address, cpu_address, size, static_cast<Tegra::PTEKind>(entry.kind),
+ use_big_pages);
}
}
std::memcpy(output.data(), entries.data(), output.size());
- return result;
+ return NvResult::Success;
}
NvResult nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8>& output) {
@@ -173,79 +327,101 @@ NvResult nvhost_as_gpu::MapBufferEx(const std::vector<u8>& input, std::vector<u8
LOG_DEBUG(Service_NVDRV,
"called, flags={:X}, nvmap_handle={:X}, buffer_offset={}, mapping_size={}"
", offset={}",
- params.flags, params.nvmap_handle, params.buffer_offset, params.mapping_size,
+ params.flags, params.handle, params.buffer_offset, params.mapping_size,
params.offset);
- const auto object{nvmap_dev->GetObject(params.nvmap_handle)};
- if (!object) {
- LOG_CRITICAL(Service_NVDRV, "invalid nvmap_handle={:X}", params.nvmap_handle);
- std::memcpy(output.data(), &params, output.size());
- return NvResult::InvalidState;
- }
-
- // The real nvservices doesn't make a distinction between handles and ids, and
- // object can only have one handle and it will be the same as its id. Assert that this is the
- // case to prevent unexpected behavior.
- ASSERT(object->id == params.nvmap_handle);
- auto& gpu = system.GPU();
+ std::scoped_lock lock(mutex);
- u64 page_size{params.page_size};
- if (!page_size) {
- page_size = object->align;
+ if (!vm.initialised) {
+ return NvResult::BadValue;
}
- if ((params.flags & AddressSpaceFlags::Remap) != AddressSpaceFlags::None) {
- if (const auto buffer_map{FindBufferMap(params.offset)}; buffer_map) {
- const auto cpu_addr{static_cast<VAddr>(buffer_map->CpuAddr() + params.buffer_offset)};
- const auto gpu_addr{static_cast<GPUVAddr>(params.offset + params.buffer_offset)};
+ // Remaps a subregion of an existing mapping to a different PA
+ if ((params.flags & MappingFlags::Remap) != MappingFlags::None) {
+ try {
+ auto mapping{mapping_map.at(params.offset)};
- if (!gpu.MemoryManager().Map(cpu_addr, gpu_addr, params.mapping_size)) {
- LOG_CRITICAL(Service_NVDRV,
- "remap failed, flags={:X}, nvmap_handle={:X}, buffer_offset={}, "
- "mapping_size = {}, offset={}",
- params.flags, params.nvmap_handle, params.buffer_offset,
- params.mapping_size, params.offset);
-
- std::memcpy(output.data(), &params, output.size());
- return NvResult::InvalidState;
+ if (mapping->size < params.mapping_size) {
+ LOG_WARNING(Service_NVDRV,
+ "Cannot remap a partially mapped GPU address space region: 0x{:X}",
+ params.offset);
+ return NvResult::BadValue;
}
- std::memcpy(output.data(), &params, output.size());
- return NvResult::Success;
- } else {
- LOG_CRITICAL(Service_NVDRV, "address not mapped offset={}", params.offset);
+ u64 gpu_address{static_cast<u64>(params.offset + params.buffer_offset)};
+ VAddr cpu_address{mapping->ptr + params.buffer_offset};
+
+ gmmu->Map(gpu_address, cpu_address, params.mapping_size,
+ static_cast<Tegra::PTEKind>(params.kind), mapping->big_page);
- std::memcpy(output.data(), &params, output.size());
- return NvResult::InvalidState;
+ return NvResult::Success;
+ } catch (const std::out_of_range&) {
+ LOG_WARNING(Service_NVDRV, "Cannot remap an unmapped GPU address space region: 0x{:X}",
+ params.offset);
+ return NvResult::BadValue;
}
}
- // We can only map objects that have already been assigned a CPU address.
- ASSERT(object->status == nvmap::Object::Status::Allocated);
-
- const auto physical_address{object->addr + params.buffer_offset};
- u64 size{params.mapping_size};
- if (!size) {
- size = object->size;
+ auto handle{nvmap.GetHandle(params.handle)};
+ if (!handle) {
+ return NvResult::BadValue;
}
- const bool is_alloc{(params.flags & AddressSpaceFlags::FixedOffset) == AddressSpaceFlags::None};
- if (is_alloc) {
- params.offset = gpu.MemoryManager().MapAllocate(physical_address, size, page_size);
- } else {
- params.offset = gpu.MemoryManager().Map(physical_address, params.offset, size);
- }
+ VAddr cpu_address{static_cast<VAddr>(handle->address + params.buffer_offset)};
+ u64 size{params.mapping_size ? params.mapping_size : handle->orig_size};
+
+ bool big_page{[&]() {
+ if (Common::IsAligned(handle->align, vm.big_page_size)) {
+ return true;
+ } else if (Common::IsAligned(handle->align, VM::YUZU_PAGESIZE)) {
+ return false;
+ } else {
+ ASSERT(false);
+ return false;
+ }
+ }()};
+
+ if ((params.flags & MappingFlags::Fixed) != MappingFlags::None) {
+ auto alloc{allocation_map.upper_bound(params.offset)};
- auto result = NvResult::Success;
- if (!params.offset) {
- LOG_CRITICAL(Service_NVDRV, "failed to map size={}", size);
- result = NvResult::InvalidState;
+ if (alloc-- == allocation_map.begin() ||
+ (params.offset - alloc->first) + size > alloc->second.size) {
+ ASSERT_MSG(false, "Cannot perform a fixed mapping into an unallocated region!");
+ return NvResult::BadValue;
+ }
+
+ const bool use_big_pages = alloc->second.big_pages && big_page;
+ gmmu->Map(params.offset, cpu_address, size, static_cast<Tegra::PTEKind>(params.kind),
+ use_big_pages);
+
+ auto mapping{std::make_shared<Mapping>(cpu_address, params.offset, size, true,
+ use_big_pages, alloc->second.sparse)};
+ alloc->second.mappings.push_back(mapping);
+ mapping_map[params.offset] = mapping;
} else {
- AddBufferMap(params.offset, size, physical_address, is_alloc);
+
+ auto& allocator{big_page ? *vm.big_page_allocator : *vm.small_page_allocator};
+ u32 page_size{big_page ? vm.big_page_size : VM::YUZU_PAGESIZE};
+ u32 page_size_bits{big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS};
+
+ params.offset = static_cast<u64>(allocator.Allocate(
+ static_cast<u32>(Common::AlignUp(size, page_size) >> page_size_bits)))
+ << page_size_bits;
+ if (!params.offset) {
+ ASSERT_MSG(false, "Failed to allocate free space in the GPU AS!");
+ return NvResult::InsufficientMemory;
+ }
+
+ gmmu->Map(params.offset, cpu_address, Common::AlignUp(size, page_size),
+ static_cast<Tegra::PTEKind>(params.kind), big_page);
+
+ auto mapping{
+ std::make_shared<Mapping>(cpu_address, params.offset, size, false, big_page, false)};
+ mapping_map[params.offset] = mapping;
}
std::memcpy(output.data(), &params, output.size());
- return result;
+ return NvResult::Success;
}
NvResult nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
@@ -254,47 +430,82 @@ NvResult nvhost_as_gpu::UnmapBuffer(const std::vector<u8>& input, std::vector<u8
LOG_DEBUG(Service_NVDRV, "called, offset=0x{:X}", params.offset);
- if (const auto size{RemoveBufferMap(params.offset)}; size) {
- system.GPU().MemoryManager().Unmap(params.offset, *size);
- } else {
- LOG_ERROR(Service_NVDRV, "invalid offset=0x{:X}", params.offset);
+ std::scoped_lock lock(mutex);
+
+ if (!vm.initialised) {
+ return NvResult::BadValue;
+ }
+
+ try {
+ auto mapping{mapping_map.at(params.offset)};
+
+ if (!mapping->fixed) {
+ auto& allocator{mapping->big_page ? *vm.big_page_allocator : *vm.small_page_allocator};
+ u32 page_size_bits{mapping->big_page ? vm.big_page_size_bits : VM::PAGE_SIZE_BITS};
+
+ allocator.Free(static_cast<u32>(mapping->offset >> page_size_bits),
+ static_cast<u32>(mapping->size >> page_size_bits));
+ }
+
+ // Sparse mappings shouldn't be fully unmapped, just returned to their sparse state
+ // Only FreeSpace can unmap them fully
+ if (mapping->sparse_alloc) {
+ gmmu->MapSparse(params.offset, mapping->size, mapping->big_page);
+ } else {
+ gmmu->Unmap(params.offset, mapping->size);
+ }
+
+ mapping_map.erase(params.offset);
+ } catch (const std::out_of_range&) {
+ LOG_WARNING(Service_NVDRV, "Couldn't find region to unmap at 0x{:X}", params.offset);
}
- std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
}
NvResult nvhost_as_gpu::BindChannel(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlBindChannel params{};
std::memcpy(&params, input.data(), input.size());
- LOG_WARNING(Service_NVDRV, "(STUBBED) called, fd={:X}", params.fd);
+ LOG_DEBUG(Service_NVDRV, "called, fd={:X}", params.fd);
- channel = params.fd;
+ auto gpu_channel_device = module.GetDevice<nvhost_gpu>(params.fd);
+ gpu_channel_device->channel_state->memory_manager = gmmu;
return NvResult::Success;
}
+void nvhost_as_gpu::GetVARegionsImpl(IoctlGetVaRegions& params) {
+ params.buf_size = 2 * sizeof(VaRegion);
+
+ params.regions = std::array<VaRegion, 2>{
+ VaRegion{
+ .offset = vm.small_page_allocator->GetVAStart() << VM::PAGE_SIZE_BITS,
+ .page_size = VM::YUZU_PAGESIZE,
+ ._pad0_{},
+ .pages = vm.small_page_allocator->GetVALimit() - vm.small_page_allocator->GetVAStart(),
+ },
+ VaRegion{
+ .offset = vm.big_page_allocator->GetVAStart() << vm.big_page_size_bits,
+ .page_size = vm.big_page_size,
+ ._pad0_{},
+ .pages = vm.big_page_allocator->GetVALimit() - vm.big_page_allocator->GetVAStart(),
+ },
+ };
+}
+
NvResult nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlGetVaRegions params{};
std::memcpy(&params, input.data(), input.size());
- LOG_WARNING(Service_NVDRV, "(STUBBED) called, buf_addr={:X}, buf_size={:X}", params.buf_addr,
- params.buf_size);
-
- params.buf_size = 0x30;
+ LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr,
+ params.buf_size);
- params.small = IoctlVaRegion{
- .offset = 0x04000000,
- .page_size = DEFAULT_SMALL_PAGE_SIZE,
- .pages = 0x3fbfff,
- };
+ std::scoped_lock lock(mutex);
- params.big = IoctlVaRegion{
- .offset = 0x04000000,
- .page_size = big_page_size,
- .pages = 0x1bffff,
- };
+ if (!vm.initialised) {
+ return NvResult::BadValue;
+ }
- // TODO(ogniK): This probably can stay stubbed but should add support way way later
+ GetVARegionsImpl(params);
std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
@@ -305,62 +516,27 @@ NvResult nvhost_as_gpu::GetVARegions(const std::vector<u8>& input, std::vector<u
IoctlGetVaRegions params{};
std::memcpy(&params, input.data(), input.size());
- LOG_WARNING(Service_NVDRV, "(STUBBED) called, buf_addr={:X}, buf_size={:X}", params.buf_addr,
- params.buf_size);
-
- params.buf_size = 0x30;
+ LOG_DEBUG(Service_NVDRV, "called, buf_addr={:X}, buf_size={:X}", params.buf_addr,
+ params.buf_size);
- params.small = IoctlVaRegion{
- .offset = 0x04000000,
- .page_size = 0x1000,
- .pages = 0x3fbfff,
- };
+ std::scoped_lock lock(mutex);
- params.big = IoctlVaRegion{
- .offset = 0x04000000,
- .page_size = big_page_size,
- .pages = 0x1bffff,
- };
+ if (!vm.initialised) {
+ return NvResult::BadValue;
+ }
- // TODO(ogniK): This probably can stay stubbed but should add support way way later
+ GetVARegionsImpl(params);
std::memcpy(output.data(), &params, output.size());
- std::memcpy(inline_output.data(), &params.small, sizeof(IoctlVaRegion));
- std::memcpy(inline_output.data() + sizeof(IoctlVaRegion), &params.big, sizeof(IoctlVaRegion));
+ std::memcpy(inline_output.data(), &params.regions[0], sizeof(VaRegion));
+ std::memcpy(inline_output.data() + sizeof(VaRegion), &params.regions[1], sizeof(VaRegion));
return NvResult::Success;
}
-std::optional<nvhost_as_gpu::BufferMap> nvhost_as_gpu::FindBufferMap(GPUVAddr gpu_addr) const {
- const auto end{buffer_mappings.upper_bound(gpu_addr)};
- for (auto iter{buffer_mappings.begin()}; iter != end; ++iter) {
- if (gpu_addr >= iter->second.StartAddr() && gpu_addr < iter->second.EndAddr()) {
- return iter->second;
- }
- }
-
- return std::nullopt;
-}
-
-void nvhost_as_gpu::AddBufferMap(GPUVAddr gpu_addr, std::size_t size, VAddr cpu_addr,
- bool is_allocated) {
- buffer_mappings[gpu_addr] = {gpu_addr, size, cpu_addr, is_allocated};
-}
-
-std::optional<std::size_t> nvhost_as_gpu::RemoveBufferMap(GPUVAddr gpu_addr) {
- if (const auto iter{buffer_mappings.find(gpu_addr)}; iter != buffer_mappings.end()) {
- std::size_t size{};
-
- if (iter->second.IsAllocated()) {
- size = iter->second.Size();
- }
-
- buffer_mappings.erase(iter);
-
- return size;
- }
-
- return std::nullopt;
+Kernel::KEvent* nvhost_as_gpu::QueryEvent(u32 event_id) {
+ LOG_CRITICAL(Service_NVDRV, "Unknown AS GPU Event {}", event_id);
+ return nullptr;
}
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
index 555843a6f..86fe71c75 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_as_gpu.h
@@ -1,35 +1,50 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
+#include <bit>
+#include <list>
#include <map>
#include <memory>
+#include <mutex>
#include <optional>
#include <vector>
+#include "common/address_space.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/swap.h"
+#include "core/hle/service/nvdrv/core/nvmap.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
-namespace Service::Nvidia::Devices {
+namespace Tegra {
+class MemoryManager;
+} // namespace Tegra
+
+namespace Service::Nvidia {
+class Module;
+}
-constexpr u32 DEFAULT_BIG_PAGE_SIZE = 1 << 16;
-constexpr u32 DEFAULT_SMALL_PAGE_SIZE = 1 << 12;
+namespace Service::Nvidia::NvCore {
+class Container;
+class NvMap;
+} // namespace Service::Nvidia::NvCore
-class nvmap;
+namespace Service::Nvidia::Devices {
-enum class AddressSpaceFlags : u32 {
- None = 0x0,
- FixedOffset = 0x1,
- Remap = 0x100,
+enum class MappingFlags : u32 {
+ None = 0,
+ Fixed = 1 << 0,
+ Sparse = 1 << 1,
+ Remap = 1 << 8,
};
-DECLARE_ENUM_FLAG_OPERATORS(AddressSpaceFlags);
+DECLARE_ENUM_FLAG_OPERATORS(MappingFlags);
class nvhost_as_gpu final : public nvdevice {
public:
- explicit nvhost_as_gpu(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_);
+ explicit nvhost_as_gpu(Core::System& system_, Module& module, NvCore::Container& core);
~nvhost_as_gpu() override;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
@@ -42,46 +57,17 @@ public:
void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override;
-private:
- class BufferMap final {
- public:
- constexpr BufferMap() = default;
-
- constexpr BufferMap(GPUVAddr start_addr_, std::size_t size_)
- : start_addr{start_addr_}, end_addr{start_addr_ + size_} {}
-
- constexpr BufferMap(GPUVAddr start_addr_, std::size_t size_, VAddr cpu_addr_,
- bool is_allocated_)
- : start_addr{start_addr_}, end_addr{start_addr_ + size_}, cpu_addr{cpu_addr_},
- is_allocated{is_allocated_} {}
-
- constexpr VAddr StartAddr() const {
- return start_addr;
- }
-
- constexpr VAddr EndAddr() const {
- return end_addr;
- }
-
- constexpr std::size_t Size() const {
- return end_addr - start_addr;
- }
-
- constexpr VAddr CpuAddr() const {
- return cpu_addr;
- }
-
- constexpr bool IsAllocated() const {
- return is_allocated;
- }
-
- private:
- GPUVAddr start_addr{};
- GPUVAddr end_addr{};
- VAddr cpu_addr{};
- bool is_allocated{};
+ Kernel::KEvent* QueryEvent(u32 event_id) override;
+
+ struct VaRegion {
+ u64 offset;
+ u32 page_size;
+ u32 _pad0_;
+ u64 pages;
};
+ static_assert(sizeof(VaRegion) == 0x18);
+private:
struct IoctlAllocAsEx {
u32_le flags{}; // usually passes 1
s32_le as_fd{}; // ignored; passes 0
@@ -96,7 +82,7 @@ private:
struct IoctlAllocSpace {
u32_le pages{};
u32_le page_size{};
- AddressSpaceFlags flags{};
+ MappingFlags flags{};
INSERT_PADDING_WORDS(1);
union {
u64_le offset;
@@ -113,19 +99,19 @@ private:
static_assert(sizeof(IoctlFreeSpace) == 16, "IoctlFreeSpace is incorrect size");
struct IoctlRemapEntry {
- u16_le flags{};
- u16_le kind{};
- u32_le nvmap_handle{};
- u32_le map_offset{};
- u32_le offset{};
- u32_le pages{};
+ u16 flags;
+ u16 kind;
+ NvCore::NvMap::Handle::Id handle;
+ u32 handle_offset_big_pages;
+ u32 as_offset_big_pages;
+ u32 big_pages;
};
static_assert(sizeof(IoctlRemapEntry) == 20, "IoctlRemapEntry is incorrect size");
struct IoctlMapBufferEx {
- AddressSpaceFlags flags{}; // bit0: fixed_offset, bit2: cacheable
- u32_le kind{}; // -1 is default
- u32_le nvmap_handle{};
+ MappingFlags flags{}; // bit0: fixed_offset, bit2: cacheable
+ u32_le kind{}; // -1 is default
+ NvCore::NvMap::Handle::Id handle;
u32_le page_size{}; // 0 means don't care
s64_le buffer_offset{};
u64_le mapping_size{};
@@ -143,27 +129,15 @@ private:
};
static_assert(sizeof(IoctlBindChannel) == 4, "IoctlBindChannel is incorrect size");
- struct IoctlVaRegion {
- u64_le offset{};
- u32_le page_size{};
- INSERT_PADDING_WORDS(1);
- u64_le pages{};
- };
- static_assert(sizeof(IoctlVaRegion) == 24, "IoctlVaRegion is incorrect size");
-
struct IoctlGetVaRegions {
u64_le buf_addr{}; // (contained output user ptr on linux, ignored)
u32_le buf_size{}; // forced to 2*sizeof(struct va_region)
u32_le reserved{};
- IoctlVaRegion small{};
- IoctlVaRegion big{};
+ std::array<VaRegion, 2> regions{};
};
- static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(IoctlVaRegion) * 2,
+ static_assert(sizeof(IoctlGetVaRegions) == 16 + sizeof(VaRegion) * 2,
"IoctlGetVaRegions is incorrect size");
- s32 channel{};
- u32 big_page_size{DEFAULT_BIG_PAGE_SIZE};
-
NvResult AllocAsEx(const std::vector<u8>& input, std::vector<u8>& output);
NvResult AllocateSpace(const std::vector<u8>& input, std::vector<u8>& output);
NvResult Remap(const std::vector<u8>& input, std::vector<u8>& output);
@@ -172,18 +146,75 @@ private:
NvResult FreeSpace(const std::vector<u8>& input, std::vector<u8>& output);
NvResult BindChannel(const std::vector<u8>& input, std::vector<u8>& output);
+ void GetVARegionsImpl(IoctlGetVaRegions& params);
NvResult GetVARegions(const std::vector<u8>& input, std::vector<u8>& output);
NvResult GetVARegions(const std::vector<u8>& input, std::vector<u8>& output,
std::vector<u8>& inline_output);
- std::optional<BufferMap> FindBufferMap(GPUVAddr gpu_addr) const;
- void AddBufferMap(GPUVAddr gpu_addr, std::size_t size, VAddr cpu_addr, bool is_allocated);
- std::optional<std::size_t> RemoveBufferMap(GPUVAddr gpu_addr);
+ void FreeMappingLocked(u64 offset);
+
+ Module& module;
+
+ NvCore::Container& container;
+ NvCore::NvMap& nvmap;
- std::shared_ptr<nvmap> nvmap_dev;
+ struct Mapping {
+ VAddr ptr;
+ u64 offset;
+ u64 size;
+ bool fixed;
+ bool big_page; // Only valid if fixed == false
+ bool sparse_alloc;
+
+ Mapping(VAddr ptr_, u64 offset_, u64 size_, bool fixed_, bool big_page_, bool sparse_alloc_)
+ : ptr(ptr_), offset(offset_), size(size_), fixed(fixed_), big_page(big_page_),
+ sparse_alloc(sparse_alloc_) {}
+ };
+
+ struct Allocation {
+ u64 size;
+ std::list<std::shared_ptr<Mapping>> mappings;
+ u32 page_size;
+ bool sparse;
+ bool big_pages;
+ };
- // This is expected to be ordered, therefore we must use a map, not unordered_map
- std::map<GPUVAddr, BufferMap> buffer_mappings;
+ std::map<u64, std::shared_ptr<Mapping>>
+ mapping_map; //!< This maps the base addresses of mapped buffers to their total sizes and
+ //!< mapping type, this is needed as what was originally a single buffer may
+ //!< have been split into multiple GPU side buffers with the remap flag.
+ std::map<u64, Allocation> allocation_map; //!< Holds allocations created by AllocSpace from
+ //!< which fixed buffers can be mapped into
+ std::mutex mutex; //!< Locks all AS operations
+
+ struct VM {
+ static constexpr u32 YUZU_PAGESIZE{0x1000};
+ static constexpr u32 PAGE_SIZE_BITS{std::countr_zero(YUZU_PAGESIZE)};
+
+ static constexpr u32 SUPPORTED_BIG_PAGE_SIZES{0x30000};
+ static constexpr u32 DEFAULT_BIG_PAGE_SIZE{0x20000};
+ u32 big_page_size{DEFAULT_BIG_PAGE_SIZE};
+ u32 big_page_size_bits{std::countr_zero(DEFAULT_BIG_PAGE_SIZE)};
+
+ static constexpr u32 VA_START_SHIFT{10};
+ static constexpr u64 DEFAULT_VA_SPLIT{1ULL << 34};
+ static constexpr u64 DEFAULT_VA_RANGE{1ULL << 37};
+ u64 va_range_start{DEFAULT_BIG_PAGE_SIZE << VA_START_SHIFT};
+ u64 va_range_split{DEFAULT_VA_SPLIT};
+ u64 va_range_end{DEFAULT_VA_RANGE};
+
+ using Allocator = Common::FlatAllocator<u32, 0, 32>;
+
+ std::unique_ptr<Allocator> big_page_allocator;
+ std::shared_ptr<Allocator>
+ small_page_allocator; //! Shared as this is also used by nvhost::GpuChannel
+
+ bool initialised{};
+ } vm;
+ std::shared_ptr<Tegra::MemoryManager> gmmu;
+
+ // s32 channel{};
+ // u32 big_page_size{VM::DEFAULT_BIG_PAGE_SIZE};
};
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 527531f29..eee11fab8 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -1,24 +1,38 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
+#include <bit>
#include <cstdlib>
#include <cstring>
+#include <fmt/format.h>
#include "common/assert.h"
#include "common/logging/log.h"
+#include "common/scope_exit.h"
#include "core/core.h"
#include "core/hle/kernel/k_event.h"
-#include "core/hle/kernel/k_writable_event.h"
+#include "core/hle/service/nvdrv/core/container.h"
+#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
#include "core/hle/service/nvdrv/devices/nvhost_ctrl.h"
#include "video_core/gpu.h"
+#include "video_core/host1x/host1x.h"
namespace Service::Nvidia::Devices {
nvhost_ctrl::nvhost_ctrl(Core::System& system_, EventInterface& events_interface_,
- SyncpointManager& syncpoint_manager_)
- : nvdevice{system_}, events_interface{events_interface_}, syncpoint_manager{
- syncpoint_manager_} {}
-nvhost_ctrl::~nvhost_ctrl() = default;
+ NvCore::Container& core_)
+ : nvdevice{system_}, events_interface{events_interface_}, core{core_},
+ syncpoint_manager{core_.GetSyncpointManager()} {}
+
+nvhost_ctrl::~nvhost_ctrl() {
+ for (auto& event : events) {
+ if (!event.registered) {
+ continue;
+ }
+ events_interface.FreeEvent(event.kevent);
+ }
+}
NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
std::vector<u8>& output) {
@@ -30,13 +44,15 @@ NvResult nvhost_ctrl::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>&
case 0x1c:
return IocCtrlClearEventWait(input, output);
case 0x1d:
- return IocCtrlEventWait(input, output, false);
- case 0x1e:
return IocCtrlEventWait(input, output, true);
+ case 0x1e:
+ return IocCtrlEventWait(input, output, false);
case 0x1f:
return IocCtrlEventRegister(input, output);
case 0x20:
return IocCtrlEventUnregister(input, output);
+ case 0x21:
+ return IocCtrlEventUnregisterBatch(input, output);
}
break;
default:
@@ -60,6 +76,7 @@ NvResult nvhost_ctrl::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>&
}
void nvhost_ctrl::OnOpen(DeviceFD fd) {}
+
void nvhost_ctrl::OnClose(DeviceFD fd) {}
NvResult nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output) {
@@ -71,116 +88,167 @@ NvResult nvhost_ctrl::NvOsGetConfigU32(const std::vector<u8>& input, std::vector
}
NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output,
- bool is_async) {
+ bool is_allocation) {
IocCtrlEventWaitParams params{};
std::memcpy(&params, input.data(), sizeof(params));
- LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_async={}",
- params.syncpt_id, params.threshold, params.timeout, is_async);
+ LOG_DEBUG(Service_NVDRV, "syncpt_id={}, threshold={}, timeout={}, is_allocation={}",
+ params.fence.id, params.fence.value, params.timeout, is_allocation);
- if (params.syncpt_id >= MaxSyncPoints) {
- return NvResult::BadParameter;
- }
+ bool must_unmark_fail = !is_allocation;
+ const u32 event_id = params.value.raw;
+ SCOPE_EXIT({
+ std::memcpy(output.data(), &params, sizeof(params));
+ if (must_unmark_fail) {
+ events[event_id].fails = 0;
+ }
+ });
- u32 event_id = params.value & 0x00FF;
+ const u32 fence_id = static_cast<u32>(params.fence.id);
- if (event_id >= MaxNvEvents) {
- std::memcpy(output.data(), &params, sizeof(params));
+ if (fence_id >= MaxSyncPoints) {
return NvResult::BadParameter;
}
- if (syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) {
- params.value = syncpoint_manager.GetSyncpointMin(params.syncpt_id);
- std::memcpy(output.data(), &params, sizeof(params));
- events_interface.failed[event_id] = false;
+ if (params.fence.value == 0) {
+ if (!syncpoint_manager.IsSyncpointAllocated(params.fence.id)) {
+ LOG_WARNING(Service_NVDRV,
+ "Unallocated syncpt_id={}, threshold={}, timeout={}, is_allocation={}",
+ params.fence.id, params.fence.value, params.timeout, is_allocation);
+ } else {
+ params.value.raw = syncpoint_manager.ReadSyncpointMinValue(fence_id);
+ }
return NvResult::Success;
}
- if (const auto new_value = syncpoint_manager.RefreshSyncpoint(params.syncpt_id);
- syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) {
- params.value = new_value;
- std::memcpy(output.data(), &params, sizeof(params));
- events_interface.failed[event_id] = false;
+ if (syncpoint_manager.IsFenceSignalled(params.fence)) {
+ params.value.raw = syncpoint_manager.ReadSyncpointMinValue(fence_id);
return NvResult::Success;
}
- auto& event = events_interface.events[event_id];
- auto& gpu = system.GPU();
-
- // This is mostly to take into account unimplemented features. As synced
- // gpu is always synced.
- if (!gpu.IsAsync()) {
- event.event->GetWritableEvent().Signal();
- return NvResult::Success;
- }
- const u32 current_syncpoint_value = event.fence.value;
- const s32 diff = current_syncpoint_value - params.threshold;
- if (diff >= 0) {
- event.event->GetWritableEvent().Signal();
- params.value = current_syncpoint_value;
- std::memcpy(output.data(), &params, sizeof(params));
- events_interface.failed[event_id] = false;
+ if (const auto new_value = syncpoint_manager.UpdateMin(fence_id);
+ syncpoint_manager.IsFenceSignalled(params.fence)) {
+ params.value.raw = new_value;
return NvResult::Success;
}
- const u32 target_value = current_syncpoint_value - diff;
- if (!is_async) {
- params.value = 0;
+ auto& host1x_syncpoint_manager = system.Host1x().GetSyncpointManager();
+ const u32 target_value = params.fence.value;
+
+ auto lock = NvEventsLock();
+
+ u32 slot = [&]() {
+ if (is_allocation) {
+ params.value.raw = 0;
+ return FindFreeNvEvent(fence_id);
+ } else {
+ return params.value.raw;
+ }
+ }();
+
+ must_unmark_fail = false;
+
+ const auto check_failing = [&]() {
+ if (events[slot].fails > 2) {
+ {
+ auto lk = system.StallProcesses();
+ host1x_syncpoint_manager.WaitHost(fence_id, target_value);
+ system.UnstallProcesses();
+ }
+ params.value.raw = target_value;
+ return true;
+ }
+ return false;
+ };
+
+ if (slot >= MaxNvEvents) {
+ return NvResult::BadParameter;
}
if (params.timeout == 0) {
- std::memcpy(output.data(), &params, sizeof(params));
+ if (check_failing()) {
+ events[slot].fails = 0;
+ return NvResult::Success;
+ }
return NvResult::Timeout;
}
- EventState status = events_interface.status[event_id];
- const bool bad_parameter = status == EventState::Busy;
- if (bad_parameter) {
- std::memcpy(output.data(), &params, sizeof(params));
+ auto& event = events[slot];
+
+ if (!event.registered) {
return NvResult::BadParameter;
}
- events_interface.SetEventStatus(event_id, EventState::Waiting);
- events_interface.assigned_syncpt[event_id] = params.syncpt_id;
- events_interface.assigned_value[event_id] = target_value;
- if (is_async) {
- params.value = params.syncpt_id << 4;
- } else {
- params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000;
- }
- params.value |= event_id;
- event.event->GetWritableEvent().Clear();
- if (events_interface.failed[event_id]) {
- {
- auto lk = system.StallProcesses();
- gpu.WaitFence(params.syncpt_id, target_value);
- system.UnstallProcesses();
- }
- std::memcpy(output.data(), &params, sizeof(params));
- events_interface.failed[event_id] = false;
+
+ if (event.IsBeingUsed()) {
+ return NvResult::BadParameter;
+ }
+
+ if (check_failing()) {
+ event.fails = 0;
return NvResult::Success;
}
- gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
- std::memcpy(output.data(), &params, sizeof(params));
+
+ params.value.raw = 0;
+
+ event.status.store(EventState::Waiting, std::memory_order_release);
+ event.assigned_syncpt = fence_id;
+ event.assigned_value = target_value;
+ if (is_allocation) {
+ params.value.syncpoint_id_for_allocation.Assign(static_cast<u16>(fence_id));
+ params.value.event_allocated.Assign(1);
+ } else {
+ params.value.syncpoint_id.Assign(fence_id);
+ }
+ params.value.raw |= slot;
+
+ event.wait_handle =
+ host1x_syncpoint_manager.RegisterHostAction(fence_id, target_value, [this, slot]() {
+ auto& event_ = events[slot];
+ if (event_.status.exchange(EventState::Signalling, std::memory_order_acq_rel) ==
+ EventState::Waiting) {
+ event_.kevent->Signal();
+ }
+ event_.status.store(EventState::Signalled, std::memory_order_release);
+ });
return NvResult::Timeout;
}
+NvResult nvhost_ctrl::FreeEvent(u32 slot) {
+ if (slot >= MaxNvEvents) {
+ return NvResult::BadParameter;
+ }
+
+ auto& event = events[slot];
+
+ if (!event.registered) {
+ return NvResult::Success;
+ }
+
+ if (event.IsBeingUsed()) {
+ return NvResult::Busy;
+ }
+
+ FreeNvEvent(slot);
+ return NvResult::Success;
+}
+
NvResult nvhost_ctrl::IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output) {
IocCtrlEventRegisterParams params{};
std::memcpy(&params, input.data(), sizeof(params));
- const u32 event_id = params.user_event_id & 0x00FF;
+ const u32 event_id = params.user_event_id;
LOG_DEBUG(Service_NVDRV, " called, user_event_id: {:X}", event_id);
if (event_id >= MaxNvEvents) {
return NvResult::BadParameter;
}
- if (events_interface.registered[event_id]) {
- const auto event_state = events_interface.status[event_id];
- if (event_state != EventState::Free) {
- LOG_WARNING(Service_NVDRV, "Event already registered! Unregistering previous event");
- events_interface.UnregisterEvent(event_id);
- } else {
- return NvResult::BadParameter;
+
+ auto lock = NvEventsLock();
+
+ if (events[event_id].registered) {
+ const auto result = FreeEvent(event_id);
+ if (result != NvResult::Success) {
+ return result;
}
}
- events_interface.RegisterEvent(event_id);
+ CreateNvEvent(event_id);
return NvResult::Success;
}
@@ -190,34 +258,142 @@ NvResult nvhost_ctrl::IocCtrlEventUnregister(const std::vector<u8>& input,
std::memcpy(&params, input.data(), sizeof(params));
const u32 event_id = params.user_event_id & 0x00FF;
LOG_DEBUG(Service_NVDRV, " called, user_event_id: {:X}", event_id);
- if (event_id >= MaxNvEvents) {
- return NvResult::BadParameter;
- }
- if (!events_interface.registered[event_id]) {
- return NvResult::BadParameter;
+
+ auto lock = NvEventsLock();
+ return FreeEvent(event_id);
+}
+
+NvResult nvhost_ctrl::IocCtrlEventUnregisterBatch(const std::vector<u8>& input,
+ std::vector<u8>& output) {
+ IocCtrlEventUnregisterBatchParams params{};
+ std::memcpy(&params, input.data(), sizeof(params));
+ u64 event_mask = params.user_events;
+ LOG_DEBUG(Service_NVDRV, " called, event_mask: {:X}", event_mask);
+
+ auto lock = NvEventsLock();
+ while (event_mask != 0) {
+ const u64 event_id = std::countr_zero(event_mask);
+ event_mask &= ~(1ULL << event_id);
+ const auto result = FreeEvent(static_cast<u32>(event_id));
+ if (result != NvResult::Success) {
+ return result;
+ }
}
- events_interface.UnregisterEvent(event_id);
return NvResult::Success;
}
NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output) {
- IocCtrlEventSignalParams params{};
+ IocCtrlEventClearParams params{};
std::memcpy(&params, input.data(), sizeof(params));
- u32 event_id = params.event_id & 0x00FF;
- LOG_WARNING(Service_NVDRV, "cleared event wait on, event_id: {:X}", event_id);
+ u32 event_id = params.event_id.slot;
+ LOG_DEBUG(Service_NVDRV, "called, event_id: {:X}", event_id);
if (event_id >= MaxNvEvents) {
return NvResult::BadParameter;
}
- if (events_interface.status[event_id] == EventState::Waiting) {
- events_interface.LiberateEvent(event_id);
- }
- events_interface.failed[event_id] = true;
- syncpoint_manager.RefreshSyncpoint(events_interface.events[event_id].fence.id);
+ auto lock = NvEventsLock();
+
+ auto& event = events[event_id];
+ if (event.status.exchange(EventState::Cancelling, std::memory_order_acq_rel) ==
+ EventState::Waiting) {
+ auto& host1x_syncpoint_manager = system.Host1x().GetSyncpointManager();
+ host1x_syncpoint_manager.DeregisterHostAction(event.assigned_syncpt, event.wait_handle);
+ syncpoint_manager.UpdateMin(event.assigned_syncpt);
+ event.wait_handle = {};
+ }
+ event.fails++;
+ event.status.store(EventState::Cancelled, std::memory_order_release);
+ event.kevent->Clear();
return NvResult::Success;
}
+Kernel::KEvent* nvhost_ctrl::QueryEvent(u32 event_id) {
+ const auto desired_event = SyncpointEventValue{.raw = event_id};
+
+ const bool allocated = desired_event.event_allocated.Value() != 0;
+ const u32 slot{allocated ? desired_event.partial_slot.Value()
+ : static_cast<u32>(desired_event.slot)};
+ if (slot >= MaxNvEvents) {
+ ASSERT(false);
+ return nullptr;
+ }
+
+ const u32 syncpoint_id{allocated ? desired_event.syncpoint_id_for_allocation.Value()
+ : desired_event.syncpoint_id.Value()};
+
+ auto lock = NvEventsLock();
+
+ auto& event = events[slot];
+ if (event.registered && event.assigned_syncpt == syncpoint_id) {
+ ASSERT(event.kevent);
+ return event.kevent;
+ }
+ // Is this possible in hardware?
+ ASSERT_MSG(false, "Slot:{}, SyncpointID:{}, requested", slot, syncpoint_id);
+ return nullptr;
+}
+
+std::unique_lock<std::mutex> nvhost_ctrl::NvEventsLock() {
+ return std::unique_lock<std::mutex>(events_mutex);
+}
+
+void nvhost_ctrl::CreateNvEvent(u32 event_id) {
+ auto& event = events[event_id];
+ ASSERT(!event.kevent);
+ ASSERT(!event.registered);
+ ASSERT(!event.IsBeingUsed());
+ event.kevent = events_interface.CreateEvent(fmt::format("NVCTRL::NvEvent_{}", event_id));
+ event.status = EventState::Available;
+ event.registered = true;
+ const u64 mask = 1ULL << event_id;
+ event.fails = 0;
+ events_mask |= mask;
+ event.assigned_syncpt = 0;
+}
+
+void nvhost_ctrl::FreeNvEvent(u32 event_id) {
+ auto& event = events[event_id];
+ ASSERT(event.kevent);
+ ASSERT(event.registered);
+ ASSERT(!event.IsBeingUsed());
+ events_interface.FreeEvent(event.kevent);
+ event.kevent = nullptr;
+ event.status = EventState::Available;
+ event.registered = false;
+ const u64 mask = ~(1ULL << event_id);
+ events_mask &= mask;
+}
+
+u32 nvhost_ctrl::FindFreeNvEvent(u32 syncpoint_id) {
+ u32 slot{MaxNvEvents};
+ u32 free_slot{MaxNvEvents};
+ for (u32 i = 0; i < MaxNvEvents; i++) {
+ auto& event = events[i];
+ if (event.registered) {
+ if (!event.IsBeingUsed()) {
+ slot = i;
+ if (event.assigned_syncpt == syncpoint_id) {
+ return slot;
+ }
+ }
+ } else if (free_slot == MaxNvEvents) {
+ free_slot = i;
+ }
+ }
+ if (free_slot < MaxNvEvents) {
+ CreateNvEvent(free_slot);
+ return free_slot;
+ }
+
+ if (slot < MaxNvEvents) {
+ return slot;
+ }
+
+ LOG_CRITICAL(Service_NVDRV, "Failed to allocate an event");
+ return 0;
+}
+
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
index 4fbb89b15..0b56d7070 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.h
@@ -1,20 +1,28 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <array>
#include <vector>
+#include "common/bit_field.h"
#include "common/common_types.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
#include "core/hle/service/nvdrv/nvdrv.h"
+#include "video_core/host1x/syncpoint_manager.h"
+
+namespace Service::Nvidia::NvCore {
+class Container;
+class SyncpointManager;
+} // namespace Service::Nvidia::NvCore
namespace Service::Nvidia::Devices {
class nvhost_ctrl final : public nvdevice {
public:
explicit nvhost_ctrl(Core::System& system_, EventInterface& events_interface_,
- SyncpointManager& syncpoint_manager_);
+ NvCore::Container& core);
~nvhost_ctrl() override;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
@@ -27,7 +35,70 @@ public:
void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override;
+ Kernel::KEvent* QueryEvent(u32 event_id) override;
+
+ union SyncpointEventValue {
+ u32 raw;
+
+ union {
+ BitField<0, 4, u32> partial_slot;
+ BitField<4, 28, u32> syncpoint_id;
+ };
+
+ struct {
+ u16 slot;
+ union {
+ BitField<0, 12, u16> syncpoint_id_for_allocation;
+ BitField<12, 1, u16> event_allocated;
+ };
+ };
+ };
+ static_assert(sizeof(SyncpointEventValue) == sizeof(u32));
+
private:
+ struct InternalEvent {
+ // Mask representing registered events
+
+ // Each kernel event associated to an NV event
+ Kernel::KEvent* kevent{};
+ // The status of the current NVEvent
+ std::atomic<EventState> status{};
+
+ // Tells the NVEvent that it has failed.
+ u32 fails{};
+ // When an NVEvent is waiting on GPU interrupt, this is the sync_point
+ // associated with it.
+ u32 assigned_syncpt{};
+ // This is the value of the GPU interrupt for which the NVEvent is waiting
+ // for.
+ u32 assigned_value{};
+
+ // Tells if an NVEvent is registered or not
+ bool registered{};
+
+ // Used for waiting on a syncpoint & canceling it.
+ Tegra::Host1x::SyncpointManager::ActionHandle wait_handle{};
+
+ bool IsBeingUsed() const {
+ const auto current_status = status.load(std::memory_order_acquire);
+ return current_status == EventState::Waiting ||
+ current_status == EventState::Cancelling ||
+ current_status == EventState::Signalling;
+ }
+ };
+
+ std::unique_lock<std::mutex> NvEventsLock();
+
+ void CreateNvEvent(u32 event_id);
+
+ void FreeNvEvent(u32 event_id);
+
+ u32 FindFreeNvEvent(u32 syncpoint_id);
+
+ std::array<InternalEvent, MaxNvEvents> events{};
+ std::mutex events_mutex;
+ u64 events_mask{};
+
struct IocSyncptReadParams {
u32_le id{};
u32_le value{};
@@ -83,27 +154,18 @@ private:
};
static_assert(sizeof(IocGetConfigParams) == 387, "IocGetConfigParams is incorrect size");
- struct IocCtrlEventSignalParams {
- u32_le event_id{};
+ struct IocCtrlEventClearParams {
+ SyncpointEventValue event_id{};
};
- static_assert(sizeof(IocCtrlEventSignalParams) == 4,
- "IocCtrlEventSignalParams is incorrect size");
+ static_assert(sizeof(IocCtrlEventClearParams) == 4,
+ "IocCtrlEventClearParams is incorrect size");
struct IocCtrlEventWaitParams {
- u32_le syncpt_id{};
- u32_le threshold{};
- s32_le timeout{};
- u32_le value{};
- };
- static_assert(sizeof(IocCtrlEventWaitParams) == 16, "IocCtrlEventWaitParams is incorrect size");
-
- struct IocCtrlEventWaitAsyncParams {
- u32_le syncpt_id{};
- u32_le threshold{};
+ NvFence fence{};
u32_le timeout{};
- u32_le value{};
+ SyncpointEventValue value{};
};
- static_assert(sizeof(IocCtrlEventWaitAsyncParams) == 16,
+ static_assert(sizeof(IocCtrlEventWaitParams) == 16,
"IocCtrlEventWaitAsyncParams is incorrect size");
struct IocCtrlEventRegisterParams {
@@ -118,19 +180,25 @@ private:
static_assert(sizeof(IocCtrlEventUnregisterParams) == 4,
"IocCtrlEventUnregisterParams is incorrect size");
- struct IocCtrlEventKill {
+ struct IocCtrlEventUnregisterBatchParams {
u64_le user_events{};
};
- static_assert(sizeof(IocCtrlEventKill) == 8, "IocCtrlEventKill is incorrect size");
+ static_assert(sizeof(IocCtrlEventUnregisterBatchParams) == 8,
+ "IocCtrlEventKill is incorrect size");
NvResult NvOsGetConfigU32(const std::vector<u8>& input, std::vector<u8>& output);
- NvResult IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output, bool is_async);
+ NvResult IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>& output,
+ bool is_allocation);
NvResult IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output);
NvResult IocCtrlEventUnregister(const std::vector<u8>& input, std::vector<u8>& output);
+ NvResult IocCtrlEventUnregisterBatch(const std::vector<u8>& input, std::vector<u8>& output);
NvResult IocCtrlClearEventWait(const std::vector<u8>& input, std::vector<u8>& output);
+ NvResult FreeEvent(u32 slot);
+
EventInterface& events_interface;
- SyncpointManager& syncpoint_manager;
+ NvCore::Container& core;
+ NvCore::SyncpointManager& syncpoint_manager;
};
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
index 2b3b7efea..ced57dfe6 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp
@@ -7,11 +7,19 @@
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h"
+#include "core/hle/service/nvdrv/nvdrv.h"
namespace Service::Nvidia::Devices {
-nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system_) : nvdevice{system_} {}
-nvhost_ctrl_gpu::~nvhost_ctrl_gpu() = default;
+nvhost_ctrl_gpu::nvhost_ctrl_gpu(Core::System& system_, EventInterface& events_interface_)
+ : nvdevice{system_}, events_interface{events_interface_} {
+ error_notifier_event = events_interface.CreateEvent("CtrlGpuErrorNotifier");
+ unknown_event = events_interface.CreateEvent("CtrlGpuUknownEvent");
+}
+nvhost_ctrl_gpu::~nvhost_ctrl_gpu() {
+ events_interface.FreeEvent(error_notifier_event);
+ events_interface.FreeEvent(unknown_event);
+}
NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
std::vector<u8>& output) {
@@ -286,4 +294,17 @@ NvResult nvhost_ctrl_gpu::GetGpuTime(const std::vector<u8>& input, std::vector<u
return NvResult::Success;
}
+Kernel::KEvent* nvhost_ctrl_gpu::QueryEvent(u32 event_id) {
+ switch (event_id) {
+ case 1:
+ return error_notifier_event;
+ case 2:
+ return unknown_event;
+ default: {
+ LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id);
+ }
+ }
+ return nullptr;
+}
+
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
index 97e9a90cb..1e8f254e2 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h
@@ -10,11 +10,15 @@
#include "common/swap.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
+namespace Service::Nvidia {
+class EventInterface;
+}
+
namespace Service::Nvidia::Devices {
class nvhost_ctrl_gpu final : public nvdevice {
public:
- explicit nvhost_ctrl_gpu(Core::System& system_);
+ explicit nvhost_ctrl_gpu(Core::System& system_, EventInterface& events_interface_);
~nvhost_ctrl_gpu() override;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
@@ -27,6 +31,8 @@ public:
void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override;
+ Kernel::KEvent* QueryEvent(u32 event_id) override;
+
private:
struct IoctlGpuCharacteristics {
u32_le arch; // 0x120 (NVGPU_GPU_ARCH_GM200)
@@ -160,6 +166,12 @@ private:
NvResult ZBCQueryTable(const std::vector<u8>& input, std::vector<u8>& output);
NvResult FlushL2(const std::vector<u8>& input, std::vector<u8>& output);
NvResult GetGpuTime(const std::vector<u8>& input, std::vector<u8>& output);
+
+ EventInterface& events_interface;
+
+ // Events
+ Kernel::KEvent* error_notifier_event;
+ Kernel::KEvent* unknown_event;
};
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index b98e63011..45a759fa8 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -5,29 +5,46 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
+#include "core/hle/service/nvdrv/core/container.h"
+#include "core/hle/service/nvdrv/core/nvmap.h"
+#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
#include "core/hle/service/nvdrv/devices/nvhost_gpu.h"
-#include "core/hle/service/nvdrv/syncpoint_manager.h"
+#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/memory.h"
+#include "video_core/control/channel_state.h"
+#include "video_core/engines/puller.h"
#include "video_core/gpu.h"
+#include "video_core/host1x/host1x.h"
namespace Service::Nvidia::Devices {
namespace {
-Tegra::CommandHeader BuildFenceAction(Tegra::GPU::FenceOperation op, u32 syncpoint_id) {
- Tegra::GPU::FenceAction result{};
+Tegra::CommandHeader BuildFenceAction(Tegra::Engines::Puller::FenceOperation op, u32 syncpoint_id) {
+ Tegra::Engines::Puller::FenceAction result{};
result.op.Assign(op);
result.syncpoint_id.Assign(syncpoint_id);
return {result.raw};
}
} // namespace
-nvhost_gpu::nvhost_gpu(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_,
- SyncpointManager& syncpoint_manager_)
- : nvdevice{system_}, nvmap_dev{std::move(nvmap_dev_)}, syncpoint_manager{syncpoint_manager_} {
- channel_fence.id = syncpoint_manager_.AllocateSyncpoint();
- channel_fence.value = system_.GPU().GetSyncpointValue(channel_fence.id);
+nvhost_gpu::nvhost_gpu(Core::System& system_, EventInterface& events_interface_,
+ NvCore::Container& core_)
+ : nvdevice{system_}, events_interface{events_interface_}, core{core_},
+ syncpoint_manager{core_.GetSyncpointManager()}, nvmap{core.GetNvMapFile()},
+ channel_state{system.GPU().AllocateChannel()} {
+ channel_syncpoint = syncpoint_manager.AllocateSyncpoint(false);
+ sm_exception_breakpoint_int_report_event =
+ events_interface.CreateEvent("GpuChannelSMExceptionBreakpointInt");
+ sm_exception_breakpoint_pause_report_event =
+ events_interface.CreateEvent("GpuChannelSMExceptionBreakpointPause");
+ error_notifier_event = events_interface.CreateEvent("GpuChannelErrorNotifier");
}
-nvhost_gpu::~nvhost_gpu() = default;
+nvhost_gpu::~nvhost_gpu() {
+ events_interface.FreeEvent(sm_exception_breakpoint_int_report_event);
+ events_interface.FreeEvent(sm_exception_breakpoint_pause_report_event);
+ events_interface.FreeEvent(error_notifier_event);
+ syncpoint_manager.FreeSyncpoint(channel_syncpoint);
+}
NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
std::vector<u8>& output) {
@@ -167,9 +184,14 @@ NvResult nvhost_gpu::AllocGPFIFOEx2(const std::vector<u8>& input, std::vector<u8
params.num_entries, params.flags, params.unk0, params.unk1, params.unk2,
params.unk3);
- channel_fence.value = system.GPU().GetSyncpointValue(channel_fence.id);
+ if (channel_state->initialized) {
+ LOG_CRITICAL(Service_NVDRV, "Already allocated!");
+ return NvResult::AlreadyAllocated;
+ }
+
+ system.GPU().InitChannel(*channel_state);
- params.fence_out = channel_fence;
+ params.fence_out = syncpoint_manager.GetSyncpointFence(channel_syncpoint);
std::memcpy(output.data(), &params, output.size());
return NvResult::Success;
@@ -188,39 +210,37 @@ NvResult nvhost_gpu::AllocateObjectContext(const std::vector<u8>& input, std::ve
static std::vector<Tegra::CommandHeader> BuildWaitCommandList(NvFence fence) {
return {
- Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceValue, 1,
+ Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1,
Tegra::SubmissionMode::Increasing),
{fence.value},
- Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1,
+ Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointOperation, 1,
Tegra::SubmissionMode::Increasing),
- BuildFenceAction(Tegra::GPU::FenceOperation::Acquire, fence.id),
+ BuildFenceAction(Tegra::Engines::Puller::FenceOperation::Acquire, fence.id),
};
}
-static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(NvFence fence,
- u32 add_increment) {
+static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(NvFence fence) {
std::vector<Tegra::CommandHeader> result{
- Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceValue, 1,
+ Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointPayload, 1,
Tegra::SubmissionMode::Increasing),
{}};
- for (u32 count = 0; count < add_increment; ++count) {
- result.emplace_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1,
+ for (u32 count = 0; count < 2; ++count) {
+ result.emplace_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::SyncpointOperation, 1,
Tegra::SubmissionMode::Increasing));
- result.emplace_back(BuildFenceAction(Tegra::GPU::FenceOperation::Increment, fence.id));
+ result.emplace_back(
+ BuildFenceAction(Tegra::Engines::Puller::FenceOperation::Increment, fence.id));
}
return result;
}
-static std::vector<Tegra::CommandHeader> BuildIncrementWithWfiCommandList(NvFence fence,
- u32 add_increment) {
+static std::vector<Tegra::CommandHeader> BuildIncrementWithWfiCommandList(NvFence fence) {
std::vector<Tegra::CommandHeader> result{
- Tegra::BuildCommandHeader(Tegra::BufferMethods::WaitForInterrupt, 1,
+ Tegra::BuildCommandHeader(Tegra::BufferMethods::WaitForIdle, 1,
Tegra::SubmissionMode::Increasing),
{}};
- const std::vector<Tegra::CommandHeader> increment{
- BuildIncrementCommandList(fence, add_increment)};
+ const std::vector<Tegra::CommandHeader> increment{BuildIncrementCommandList(fence)};
result.insert(result.end(), increment.begin(), increment.end());
@@ -234,33 +254,41 @@ NvResult nvhost_gpu::SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, std::vector<u8>
auto& gpu = system.GPU();
- params.fence_out.id = channel_fence.id;
+ std::scoped_lock lock(channel_mutex);
- if (params.flags.add_wait.Value() &&
- !syncpoint_manager.IsSyncpointExpired(params.fence_out.id, params.fence_out.value)) {
- gpu.PushGPUEntries(Tegra::CommandList{BuildWaitCommandList(params.fence_out)});
- }
+ const auto bind_id = channel_state->bind_id;
- if (params.flags.add_increment.Value() || params.flags.increment.Value()) {
- const u32 increment_value = params.flags.increment.Value() ? params.fence_out.value : 0;
- params.fence_out.value = syncpoint_manager.IncreaseSyncpoint(
- params.fence_out.id, params.AddIncrementValue() + increment_value);
- } else {
- params.fence_out.value = syncpoint_manager.GetSyncpointMax(params.fence_out.id);
+ auto& flags = params.flags;
+
+ if (flags.fence_wait.Value()) {
+ if (flags.increment_value.Value()) {
+ return NvResult::BadParameter;
+ }
+
+ if (!syncpoint_manager.IsFenceSignalled(params.fence)) {
+ gpu.PushGPUEntries(bind_id, Tegra::CommandList{BuildWaitCommandList(params.fence)});
+ }
}
- gpu.PushGPUEntries(std::move(entries));
+ params.fence.id = channel_syncpoint;
+
+ u32 increment{(flags.fence_increment.Value() != 0 ? 2 : 0) +
+ (flags.increment_value.Value() != 0 ? params.fence.value : 0)};
+ params.fence.value = syncpoint_manager.IncrementSyncpointMaxExt(channel_syncpoint, increment);
+ gpu.PushGPUEntries(bind_id, std::move(entries));
- if (params.flags.add_increment.Value()) {
- if (params.flags.suppress_wfi) {
- gpu.PushGPUEntries(Tegra::CommandList{
- BuildIncrementCommandList(params.fence_out, params.AddIncrementValue())});
+ if (flags.fence_increment.Value()) {
+ if (flags.suppress_wfi.Value()) {
+ gpu.PushGPUEntries(bind_id,
+ Tegra::CommandList{BuildIncrementCommandList(params.fence)});
} else {
- gpu.PushGPUEntries(Tegra::CommandList{
- BuildIncrementWithWfiCommandList(params.fence_out, params.AddIncrementValue())});
+ gpu.PushGPUEntries(bind_id,
+ Tegra::CommandList{BuildIncrementWithWfiCommandList(params.fence)});
}
}
+ flags.raw = 0;
+
std::memcpy(output.data(), &params, sizeof(IoctlSubmitGpfifo));
return NvResult::Success;
}
@@ -328,4 +356,19 @@ NvResult nvhost_gpu::ChannelSetTimeslice(const std::vector<u8>& input, std::vect
return NvResult::Success;
}
+Kernel::KEvent* nvhost_gpu::QueryEvent(u32 event_id) {
+ switch (event_id) {
+ case 1:
+ return sm_exception_breakpoint_int_report_event;
+ case 2:
+ return sm_exception_breakpoint_pause_report_event;
+ case 3:
+ return error_notifier_event;
+ default: {
+ LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id);
+ }
+ }
+ return nullptr;
+}
+
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
index 8a9f7775a..1e4ecd55b 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h
@@ -13,17 +13,31 @@
#include "core/hle/service/nvdrv/nvdata.h"
#include "video_core/dma_pusher.h"
+namespace Tegra {
+namespace Control {
+struct ChannelState;
+}
+} // namespace Tegra
+
namespace Service::Nvidia {
+
+namespace NvCore {
+class Container;
+class NvMap;
class SyncpointManager;
-}
+} // namespace NvCore
+
+class EventInterface;
+} // namespace Service::Nvidia
namespace Service::Nvidia::Devices {
+class nvhost_as_gpu;
class nvmap;
class nvhost_gpu final : public nvdevice {
public:
- explicit nvhost_gpu(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_,
- SyncpointManager& syncpoint_manager_);
+ explicit nvhost_gpu(Core::System& system_, EventInterface& events_interface_,
+ NvCore::Container& core);
~nvhost_gpu() override;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
@@ -36,7 +50,10 @@ public:
void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override;
+ Kernel::KEvent* QueryEvent(u32 event_id) override;
+
private:
+ friend class nvhost_as_gpu;
enum class CtxObjects : u32_le {
Ctx2D = 0x902D,
Ctx3D = 0xB197,
@@ -146,17 +163,13 @@ private:
u32_le num_entries{}; // number of fence objects being submitted
union {
u32_le raw;
- BitField<0, 1, u32_le> add_wait; // append a wait sync_point to the list
- BitField<1, 1, u32_le> add_increment; // append an increment to the list
- BitField<2, 1, u32_le> new_hw_format; // mostly ignored
- BitField<4, 1, u32_le> suppress_wfi; // suppress wait for interrupt
- BitField<8, 1, u32_le> increment; // increment the returned fence
+ BitField<0, 1, u32_le> fence_wait; // append a wait sync_point to the list
+ BitField<1, 1, u32_le> fence_increment; // append an increment to the list
+ BitField<2, 1, u32_le> new_hw_format; // mostly ignored
+ BitField<4, 1, u32_le> suppress_wfi; // suppress wait for interrupt
+ BitField<8, 1, u32_le> increment_value; // increment the returned fence
} flags;
- NvFence fence_out{}; // returned new fence object for others to wait on
-
- u32 AddIncrementValue() const {
- return flags.add_increment.Value() << 1;
- }
+ NvFence fence{}; // returned new fence object for others to wait on
};
static_assert(sizeof(IoctlSubmitGpfifo) == 16 + sizeof(NvFence),
"IoctlSubmitGpfifo is incorrect size");
@@ -191,9 +204,18 @@ private:
NvResult ChannelSetTimeout(const std::vector<u8>& input, std::vector<u8>& output);
NvResult ChannelSetTimeslice(const std::vector<u8>& input, std::vector<u8>& output);
- std::shared_ptr<nvmap> nvmap_dev;
- SyncpointManager& syncpoint_manager;
- NvFence channel_fence;
+ EventInterface& events_interface;
+ NvCore::Container& core;
+ NvCore::SyncpointManager& syncpoint_manager;
+ NvCore::NvMap& nvmap;
+ std::shared_ptr<Tegra::Control::ChannelState> channel_state;
+ u32 channel_syncpoint;
+ std::mutex channel_mutex;
+
+ // Events
+ Kernel::KEvent* sm_exception_breakpoint_int_report_event;
+ Kernel::KEvent* sm_exception_breakpoint_pause_report_event;
+ Kernel::KEvent* error_notifier_event;
};
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index a7385fce8..1703f9cc3 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -5,14 +5,14 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
+#include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/devices/nvhost_nvdec.h"
#include "video_core/renderer_base.h"
namespace Service::Nvidia::Devices {
-nvhost_nvdec::nvhost_nvdec(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_,
- SyncpointManager& syncpoint_manager_)
- : nvhost_nvdec_common{system_, std::move(nvmap_dev_), syncpoint_manager_} {}
+nvhost_nvdec::nvhost_nvdec(Core::System& system_, NvCore::Container& core_)
+ : nvhost_nvdec_common{system_, core_, NvCore::ChannelType::NvDec} {}
nvhost_nvdec::~nvhost_nvdec() = default;
NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
@@ -21,8 +21,9 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>&
case 0x0:
switch (command.cmd) {
case 0x1: {
- if (!fd_to_id.contains(fd)) {
- fd_to_id[fd] = next_id++;
+ auto& host1x_file = core.Host1xDeviceFile();
+ if (!host1x_file.fd_to_id.contains(fd)) {
+ host1x_file.fd_to_id[fd] = host1x_file.nvdec_next_id++;
}
return Submit(fd, input, output);
}
@@ -73,8 +74,9 @@ void nvhost_nvdec::OnOpen(DeviceFD fd) {
void nvhost_nvdec::OnClose(DeviceFD fd) {
LOG_INFO(Service_NVDRV, "NVDEC video stream ended");
- const auto iter = fd_to_id.find(fd);
- if (iter != fd_to_id.end()) {
+ auto& host1x_file = core.Host1xDeviceFile();
+ const auto iter = host1x_file.fd_to_id.find(fd);
+ if (iter != host1x_file.fd_to_id.end()) {
system.GPU().ClearCdmaInstance(iter->second);
}
system.AudioCore().SetNVDECActive(false);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index 29b3e6a36..c1b4e53e8 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -10,8 +10,7 @@ namespace Service::Nvidia::Devices {
class nvhost_nvdec final : public nvhost_nvdec_common {
public:
- explicit nvhost_nvdec(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_,
- SyncpointManager& syncpoint_manager_);
+ explicit nvhost_nvdec(Core::System& system_, NvCore::Container& core);
~nvhost_nvdec() override;
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
@@ -23,9 +22,6 @@ public:
void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override;
-
-private:
- u32 next_id{};
};
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
index 8b2cd9bf1..99eede702 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -8,10 +8,12 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "core/core.h"
+#include "core/hle/service/nvdrv/core/container.h"
+#include "core/hle/service/nvdrv/core/nvmap.h"
+#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
#include "core/hle/service/nvdrv/devices/nvhost_nvdec_common.h"
-#include "core/hle/service/nvdrv/devices/nvmap.h"
-#include "core/hle/service/nvdrv/syncpoint_manager.h"
#include "core/memory.h"
+#include "video_core/host1x/host1x.h"
#include "video_core/memory_manager.h"
#include "video_core/renderer_base.h"
@@ -44,10 +46,22 @@ std::size_t WriteVectors(std::vector<u8>& dst, const std::vector<T>& src, std::s
}
} // Anonymous namespace
-nvhost_nvdec_common::nvhost_nvdec_common(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_,
- SyncpointManager& syncpoint_manager_)
- : nvdevice{system_}, nvmap_dev{std::move(nvmap_dev_)}, syncpoint_manager{syncpoint_manager_} {}
-nvhost_nvdec_common::~nvhost_nvdec_common() = default;
+nvhost_nvdec_common::nvhost_nvdec_common(Core::System& system_, NvCore::Container& core_,
+ NvCore::ChannelType channel_type_)
+ : nvdevice{system_}, core{core_}, syncpoint_manager{core.GetSyncpointManager()},
+ nvmap{core.GetNvMapFile()}, channel_type{channel_type_} {
+ auto& syncpts_accumulated = core.Host1xDeviceFile().syncpts_accumulated;
+ if (syncpts_accumulated.empty()) {
+ channel_syncpoint = syncpoint_manager.AllocateSyncpoint(false);
+ } else {
+ channel_syncpoint = syncpts_accumulated.front();
+ syncpts_accumulated.pop_front();
+ }
+}
+
+nvhost_nvdec_common::~nvhost_nvdec_common() {
+ core.Host1xDeviceFile().syncpts_accumulated.push_back(channel_syncpoint);
+}
NvResult nvhost_nvdec_common::SetNVMAPfd(const std::vector<u8>& input) {
IoctlSetNvmapFD params{};
@@ -84,16 +98,16 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, const std::vector<u8>& input,
for (std::size_t i = 0; i < syncpt_increments.size(); i++) {
const SyncptIncr& syncpt_incr = syncpt_increments[i];
fence_thresholds[i] =
- syncpoint_manager.IncreaseSyncpoint(syncpt_incr.id, syncpt_incr.increments);
+ syncpoint_manager.IncrementSyncpointMaxExt(syncpt_incr.id, syncpt_incr.increments);
}
}
for (const auto& cmd_buffer : command_buffers) {
- const auto object = nvmap_dev->GetObject(cmd_buffer.memory_id);
+ const auto object = nvmap.GetHandle(cmd_buffer.memory_id);
ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;);
Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count);
- system.Memory().ReadBlock(object->addr + cmd_buffer.offset, cmdlist.data(),
+ system.Memory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(),
cmdlist.size() * sizeof(u32));
- gpu.PushCommandBuffer(fd_to_id[fd], cmdlist);
+ gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist);
}
std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
// Some games expect command_buffers to be written back
@@ -112,10 +126,8 @@ NvResult nvhost_nvdec_common::GetSyncpoint(const std::vector<u8>& input, std::ve
std::memcpy(&params, input.data(), sizeof(IoctlGetSyncpoint));
LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param);
- if (device_syncpoints[params.param] == 0 && system.GPU().UseNvdec()) {
- device_syncpoints[params.param] = syncpoint_manager.AllocateSyncpoint();
- }
- params.value = device_syncpoints[params.param];
+ // const u32 id{NvCore::SyncpointManager::channel_syncpoints[static_cast<u32>(channel_type)]};
+ params.value = channel_syncpoint;
std::memcpy(output.data(), &params, sizeof(IoctlGetSyncpoint));
return NvResult::Success;
@@ -123,6 +135,7 @@ NvResult nvhost_nvdec_common::GetSyncpoint(const std::vector<u8>& input, std::ve
NvResult nvhost_nvdec_common::GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output) {
IoctlGetWaitbase params{};
+ LOG_CRITICAL(Service_NVDRV, "called WAITBASE");
std::memcpy(&params, input.data(), sizeof(IoctlGetWaitbase));
params.value = 0; // Seems to be hard coded at 0
std::memcpy(output.data(), &params, sizeof(IoctlGetWaitbase));
@@ -136,28 +149,8 @@ NvResult nvhost_nvdec_common::MapBuffer(const std::vector<u8>& input, std::vecto
SliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer));
- auto& gpu = system.GPU();
-
for (auto& cmd_buffer : cmd_buffer_handles) {
- auto object{nvmap_dev->GetObject(cmd_buffer.map_handle)};
- if (!object) {
- LOG_ERROR(Service_NVDRV, "invalid cmd_buffer nvmap_handle={:X}", cmd_buffer.map_handle);
- std::memcpy(output.data(), &params, output.size());
- return NvResult::InvalidState;
- }
- if (object->dma_map_addr == 0) {
- // NVDEC and VIC memory is in the 32-bit address space
- // MapAllocate32 will attempt to map a lower 32-bit value in the shared gpu memory space
- const GPUVAddr low_addr = gpu.MemoryManager().MapAllocate32(object->addr, object->size);
- object->dma_map_addr = static_cast<u32>(low_addr);
- // Ensure that the dma_map_addr is indeed in the lower 32-bit address space.
- ASSERT(object->dma_map_addr == low_addr);
- }
- if (!object->dma_map_addr) {
- LOG_ERROR(Service_NVDRV, "failed to map size={}", object->size);
- } else {
- cmd_buffer.map_address = object->dma_map_addr;
- }
+ cmd_buffer.map_address = nvmap.PinHandle(cmd_buffer.map_handle);
}
std::memcpy(output.data(), &params, sizeof(IoctlMapBuffer));
std::memcpy(output.data() + sizeof(IoctlMapBuffer), cmd_buffer_handles.data(),
@@ -167,11 +160,16 @@ NvResult nvhost_nvdec_common::MapBuffer(const std::vector<u8>& input, std::vecto
}
NvResult nvhost_nvdec_common::UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output) {
- // This is intntionally stubbed.
- // Skip unmapping buffers here, as to not break the continuity of the VP9 reference frame
- // addresses, and risk invalidating data before the async GPU thread is done with it
+ IoctlMapBuffer params{};
+ std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
+ std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries);
+
+ SliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer));
+ for (auto& cmd_buffer : cmd_buffer_handles) {
+ nvmap.UnpinHandle(cmd_buffer.map_handle);
+ }
+
std::memset(output.data(), 0, output.size());
- LOG_DEBUG(Service_NVDRV, "(STUBBED) called");
return NvResult::Success;
}
@@ -182,4 +180,9 @@ NvResult nvhost_nvdec_common::SetSubmitTimeout(const std::vector<u8>& input,
return NvResult::Success;
}
+Kernel::KEvent* nvhost_nvdec_common::QueryEvent(u32 event_id) {
+ LOG_CRITICAL(Service_NVDRV, "Unknown HOSTX1 Event {}", event_id);
+ return nullptr;
+}
+
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
index 12d39946d..fe76100c8 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
@@ -3,21 +3,26 @@
#pragma once
+#include <deque>
#include <vector>
#include "common/common_types.h"
#include "common/swap.h"
+#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
namespace Service::Nvidia {
-class SyncpointManager;
+
+namespace NvCore {
+class Container;
+class NvMap;
+} // namespace NvCore
namespace Devices {
-class nvmap;
class nvhost_nvdec_common : public nvdevice {
public:
- explicit nvhost_nvdec_common(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_,
- SyncpointManager& syncpoint_manager_);
+ explicit nvhost_nvdec_common(Core::System& system_, NvCore::Container& core,
+ NvCore::ChannelType channel_type);
~nvhost_nvdec_common() override;
protected:
@@ -110,11 +115,15 @@ protected:
NvResult UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
NvResult SetSubmitTimeout(const std::vector<u8>& input, std::vector<u8>& output);
- std::unordered_map<DeviceFD, u32> fd_to_id{};
+ Kernel::KEvent* QueryEvent(u32 event_id) override;
+
+ u32 channel_syncpoint;
s32_le nvmap_fd{};
u32_le submit_timeout{};
- std::shared_ptr<nvmap> nvmap_dev;
- SyncpointManager& syncpoint_manager;
+ NvCore::Container& core;
+ NvCore::SyncpointManager& syncpoint_manager;
+ NvCore::NvMap& nvmap;
+ NvCore::ChannelType channel_type;
std::array<u32, MaxSyncPoints> device_syncpoints{};
};
}; // namespace Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index f58e8bada..73f97136e 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -4,13 +4,14 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
+#include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/devices/nvhost_vic.h"
#include "video_core/renderer_base.h"
namespace Service::Nvidia::Devices {
-nvhost_vic::nvhost_vic(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_,
- SyncpointManager& syncpoint_manager_)
- : nvhost_nvdec_common{system_, std::move(nvmap_dev_), syncpoint_manager_} {}
+
+nvhost_vic::nvhost_vic(Core::System& system_, NvCore::Container& core_)
+ : nvhost_nvdec_common{system_, core_, NvCore::ChannelType::VIC} {}
nvhost_vic::~nvhost_vic() = default;
@@ -19,11 +20,13 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& i
switch (command.group) {
case 0x0:
switch (command.cmd) {
- case 0x1:
- if (!fd_to_id.contains(fd)) {
- fd_to_id[fd] = next_id++;
+ case 0x1: {
+ auto& host1x_file = core.Host1xDeviceFile();
+ if (!host1x_file.fd_to_id.contains(fd)) {
+ host1x_file.fd_to_id[fd] = host1x_file.vic_next_id++;
}
return Submit(fd, input, output);
+ }
case 0x2:
return GetSyncpoint(input, output);
case 0x3:
@@ -67,8 +70,9 @@ NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& i
void nvhost_vic::OnOpen(DeviceFD fd) {}
void nvhost_vic::OnClose(DeviceFD fd) {
- const auto iter = fd_to_id.find(fd);
- if (iter != fd_to_id.end()) {
+ auto& host1x_file = core.Host1xDeviceFile();
+ const auto iter = host1x_file.fd_to_id.find(fd);
+ if (iter != host1x_file.fd_to_id.end()) {
system.GPU().ClearCdmaInstance(iter->second);
}
}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
index b41b195ae..f164caafb 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
@@ -9,8 +9,7 @@ namespace Service::Nvidia::Devices {
class nvhost_vic final : public nvhost_nvdec_common {
public:
- explicit nvhost_vic(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_,
- SyncpointManager& syncpoint_manager_);
+ explicit nvhost_vic(Core::System& system_, NvCore::Container& core);
~nvhost_vic();
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
@@ -22,8 +21,5 @@ public:
void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override;
-
-private:
- u32 next_id{};
};
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.cpp b/src/core/hle/service/nvdrv/devices/nvmap.cpp
index d8518149d..44388655d 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvmap.cpp
@@ -2,19 +2,26 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
+#include <bit>
#include <cstring>
+#include "common/alignment.h"
#include "common/assert.h"
#include "common/logging/log.h"
+#include "core/core.h"
+#include "core/hle/kernel/k_page_table.h"
+#include "core/hle/kernel/k_process.h"
+#include "core/hle/service/nvdrv/core/container.h"
+#include "core/hle/service/nvdrv/core/nvmap.h"
#include "core/hle/service/nvdrv/devices/nvmap.h"
+#include "core/memory.h"
+
+using Core::Memory::YUZU_PAGESIZE;
namespace Service::Nvidia::Devices {
-nvmap::nvmap(Core::System& system_) : nvdevice{system_} {
- // Handle 0 appears to be used when remapping, so we create a placeholder empty nvmap object to
- // represent this.
- CreateObject(0);
-}
+nvmap::nvmap(Core::System& system_, NvCore::Container& container_)
+ : nvdevice{system_}, container{container_}, file{container.GetNvMapFile()} {}
nvmap::~nvmap() = default;
@@ -62,39 +69,21 @@ NvResult nvmap::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
void nvmap::OnOpen(DeviceFD fd) {}
void nvmap::OnClose(DeviceFD fd) {}
-VAddr nvmap::GetObjectAddress(u32 handle) const {
- auto object = GetObject(handle);
- ASSERT(object);
- ASSERT(object->status == Object::Status::Allocated);
- return object->addr;
-}
-
-u32 nvmap::CreateObject(u32 size) {
- // Create a new nvmap object and obtain a handle to it.
- auto object = std::make_shared<Object>();
- object->id = next_id++;
- object->size = size;
- object->status = Object::Status::Created;
- object->refcount = 1;
-
- const u32 handle = next_handle++;
-
- handles.insert_or_assign(handle, std::move(object));
-
- return handle;
-}
-
NvResult nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output) {
IocCreateParams params;
std::memcpy(&params, input.data(), sizeof(params));
- LOG_DEBUG(Service_NVDRV, "size=0x{:08X}", params.size);
-
- if (!params.size) {
- LOG_ERROR(Service_NVDRV, "Size is 0");
- return NvResult::BadValue;
+ LOG_DEBUG(Service_NVDRV, "called, size=0x{:08X}", params.size);
+
+ std::shared_ptr<NvCore::NvMap::Handle> handle_description{};
+ auto result =
+ file.CreateHandle(Common::AlignUp(params.size, YUZU_PAGESIZE), handle_description);
+ if (result != NvResult::Success) {
+ LOG_CRITICAL(Service_NVDRV, "Failed to create Object");
+ return result;
}
-
- params.handle = CreateObject(params.size);
+ handle_description->orig_size = params.size; // Orig size is the unaligned size
+ params.handle = handle_description->id;
+ LOG_DEBUG(Service_NVDRV, "handle: {}, size: 0x{:X}", handle_description->id, params.size);
std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success;
@@ -103,63 +92,69 @@ NvResult nvmap::IocCreate(const std::vector<u8>& input, std::vector<u8>& output)
NvResult nvmap::IocAlloc(const std::vector<u8>& input, std::vector<u8>& output) {
IocAllocParams params;
std::memcpy(&params, input.data(), sizeof(params));
- LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.addr);
+ LOG_DEBUG(Service_NVDRV, "called, addr={:X}", params.address);
if (!params.handle) {
- LOG_ERROR(Service_NVDRV, "Handle is 0");
+ LOG_CRITICAL(Service_NVDRV, "Handle is 0");
return NvResult::BadValue;
}
if ((params.align - 1) & params.align) {
- LOG_ERROR(Service_NVDRV, "Incorrect alignment used, alignment={:08X}", params.align);
+ LOG_CRITICAL(Service_NVDRV, "Incorrect alignment used, alignment={:08X}", params.align);
return NvResult::BadValue;
}
- const u32 min_alignment = 0x1000;
- if (params.align < min_alignment) {
- params.align = min_alignment;
+ // Force page size alignment at a minimum
+ if (params.align < YUZU_PAGESIZE) {
+ params.align = YUZU_PAGESIZE;
}
- auto object = GetObject(params.handle);
- if (!object) {
- LOG_ERROR(Service_NVDRV, "Object does not exist, handle={:08X}", params.handle);
+ auto handle_description{file.GetHandle(params.handle)};
+ if (!handle_description) {
+ LOG_CRITICAL(Service_NVDRV, "Object does not exist, handle={:08X}", params.handle);
return NvResult::BadValue;
}
- if (object->status == Object::Status::Allocated) {
- LOG_ERROR(Service_NVDRV, "Object is already allocated, handle={:08X}", params.handle);
+ if (handle_description->allocated) {
+ LOG_CRITICAL(Service_NVDRV, "Object is already allocated, handle={:08X}", params.handle);
return NvResult::InsufficientMemory;
}
- object->flags = params.flags;
- object->align = params.align;
- object->kind = params.kind;
- object->addr = params.addr;
- object->status = Object::Status::Allocated;
-
+ const auto result =
+ handle_description->Alloc(params.flags, params.align, params.kind, params.address);
+ if (result != NvResult::Success) {
+ LOG_CRITICAL(Service_NVDRV, "Object failed to allocate, handle={:08X}", params.handle);
+ return result;
+ }
+ ASSERT(system.CurrentProcess()
+ ->PageTable()
+ .LockForMapDeviceAddressSpace(handle_description->address, handle_description->size,
+ Kernel::KMemoryPermission::None, true)
+ .IsSuccess());
std::memcpy(output.data(), &params, sizeof(params));
- return NvResult::Success;
+ return result;
}
NvResult nvmap::IocGetId(const std::vector<u8>& input, std::vector<u8>& output) {
IocGetIdParams params;
std::memcpy(&params, input.data(), sizeof(params));
- LOG_WARNING(Service_NVDRV, "called");
+ LOG_DEBUG(Service_NVDRV, "called");
+ // See the comment in FromId for extra info on this function
if (!params.handle) {
- LOG_ERROR(Service_NVDRV, "Handle is zero");
+ LOG_CRITICAL(Service_NVDRV, "Error!");
return NvResult::BadValue;
}
- auto object = GetObject(params.handle);
- if (!object) {
- LOG_ERROR(Service_NVDRV, "Object does not exist, handle={:08X}", params.handle);
- return NvResult::BadValue;
+ auto handle_description{file.GetHandle(params.handle)};
+ if (!handle_description) {
+ LOG_CRITICAL(Service_NVDRV, "Error!");
+ return NvResult::AccessDenied; // This will always return EPERM irrespective of if the
+ // handle exists or not
}
- params.id = object->id;
-
+ params.id = handle_description->id;
std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success;
}
@@ -168,26 +163,29 @@ NvResult nvmap::IocFromId(const std::vector<u8>& input, std::vector<u8>& output)
IocFromIdParams params;
std::memcpy(&params, input.data(), sizeof(params));
- LOG_WARNING(Service_NVDRV, "(STUBBED) called");
+ LOG_DEBUG(Service_NVDRV, "called, id:{}", params.id);
- auto itr = std::find_if(handles.begin(), handles.end(),
- [&](const auto& entry) { return entry.second->id == params.id; });
- if (itr == handles.end()) {
- LOG_ERROR(Service_NVDRV, "Object does not exist, handle={:08X}", params.handle);
+ // Handles and IDs are always the same value in nvmap however IDs can be used globally given the
+ // right permissions.
+ // Since we don't plan on ever supporting multiprocess we can skip implementing handle refs and
+ // so this function just does simple validation and passes through the handle id.
+ if (!params.id) {
+ LOG_CRITICAL(Service_NVDRV, "Zero Id is invalid!");
return NvResult::BadValue;
}
- auto& object = itr->second;
- if (object->status != Object::Status::Allocated) {
- LOG_ERROR(Service_NVDRV, "Object is not allocated, handle={:08X}", params.handle);
+ auto handle_description{file.GetHandle(params.id)};
+ if (!handle_description) {
+ LOG_CRITICAL(Service_NVDRV, "Unregistered handle!");
return NvResult::BadValue;
}
- itr->second->refcount++;
-
- // Return the existing handle instead of creating a new one.
- params.handle = itr->first;
-
+ auto result = handle_description->Duplicate(false);
+ if (result != NvResult::Success) {
+ LOG_CRITICAL(Service_NVDRV, "Could not duplicate handle!");
+ return result;
+ }
+ params.handle = handle_description->id;
std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success;
}
@@ -198,35 +196,43 @@ NvResult nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output)
IocParamParams params;
std::memcpy(&params, input.data(), sizeof(params));
- LOG_DEBUG(Service_NVDRV, "(STUBBED) called type={}", params.param);
+ LOG_DEBUG(Service_NVDRV, "called type={}", params.param);
- auto object = GetObject(params.handle);
- if (!object) {
- LOG_ERROR(Service_NVDRV, "Object does not exist, handle={:08X}", params.handle);
+ if (!params.handle) {
+ LOG_CRITICAL(Service_NVDRV, "Invalid handle!");
return NvResult::BadValue;
}
- if (object->status != Object::Status::Allocated) {
- LOG_ERROR(Service_NVDRV, "Object is not allocated, handle={:08X}", params.handle);
+ auto handle_description{file.GetHandle(params.handle)};
+ if (!handle_description) {
+ LOG_CRITICAL(Service_NVDRV, "Not registered handle!");
return NvResult::BadValue;
}
- switch (static_cast<ParamTypes>(params.param)) {
- case ParamTypes::Size:
- params.result = object->size;
+ switch (params.param) {
+ case HandleParameterType::Size:
+ params.result = static_cast<u32_le>(handle_description->orig_size);
break;
- case ParamTypes::Alignment:
- params.result = object->align;
+ case HandleParameterType::Alignment:
+ params.result = static_cast<u32_le>(handle_description->align);
break;
- case ParamTypes::Heap:
- // TODO(Subv): Seems to be a hardcoded value?
- params.result = 0x40000000;
+ case HandleParameterType::Base:
+ params.result = static_cast<u32_le>(-22); // posix EINVAL
break;
- case ParamTypes::Kind:
- params.result = object->kind;
+ case HandleParameterType::Heap:
+ if (handle_description->allocated)
+ params.result = 0x40000000;
+ else
+ params.result = 0;
+ break;
+ case HandleParameterType::Kind:
+ params.result = handle_description->kind;
+ break;
+ case HandleParameterType::IsSharedMemMapped:
+ params.result = handle_description->is_shared_mem_mapped;
break;
default:
- UNIMPLEMENTED();
+ return NvResult::BadValue;
}
std::memcpy(output.data(), &params, sizeof(params));
@@ -234,46 +240,31 @@ NvResult nvmap::IocParam(const std::vector<u8>& input, std::vector<u8>& output)
}
NvResult nvmap::IocFree(const std::vector<u8>& input, std::vector<u8>& output) {
- // TODO(Subv): These flags are unconfirmed.
- enum FreeFlags {
- Freed = 0,
- NotFreedYet = 1,
- };
-
IocFreeParams params;
std::memcpy(&params, input.data(), sizeof(params));
- LOG_DEBUG(Service_NVDRV, "(STUBBED) called");
+ LOG_DEBUG(Service_NVDRV, "called");
- auto itr = handles.find(params.handle);
- if (itr == handles.end()) {
- LOG_ERROR(Service_NVDRV, "Object does not exist, handle={:08X}", params.handle);
- return NvResult::BadValue;
- }
- if (!itr->second->refcount) {
- LOG_ERROR(
- Service_NVDRV,
- "There is no references to this object. The object is already freed. handle={:08X}",
- params.handle);
- return NvResult::BadValue;
+ if (!params.handle) {
+ LOG_CRITICAL(Service_NVDRV, "Handle null freed?");
+ return NvResult::Success;
}
- itr->second->refcount--;
-
- params.size = itr->second->size;
-
- if (itr->second->refcount == 0) {
- params.flags = Freed;
- // The address of the nvmap is written to the output if we're finally freeing it, otherwise
- // 0 is written.
- params.address = itr->second->addr;
+ if (auto freeInfo{file.FreeHandle(params.handle, false)}) {
+ if (freeInfo->can_unlock) {
+ ASSERT(system.CurrentProcess()
+ ->PageTable()
+ .UnlockForDeviceAddressSpace(freeInfo->address, freeInfo->size)
+ .IsSuccess());
+ }
+ params.address = freeInfo->address;
+ params.size = static_cast<u32>(freeInfo->size);
+ params.flags.raw = 0;
+ params.flags.map_uncached.Assign(freeInfo->was_uncached);
} else {
- params.flags = NotFreedYet;
- params.address = 0;
+ // This is possible when there's internel dups or other duplicates.
}
- handles.erase(params.handle);
-
std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success;
}
diff --git a/src/core/hle/service/nvdrv/devices/nvmap.h b/src/core/hle/service/nvdrv/devices/nvmap.h
index d5360d6e5..e9bfd0358 100644
--- a/src/core/hle/service/nvdrv/devices/nvmap.h
+++ b/src/core/hle/service/nvdrv/devices/nvmap.h
@@ -9,15 +9,23 @@
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/swap.h"
+#include "core/hle/service/nvdrv/core/nvmap.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
+namespace Service::Nvidia::NvCore {
+class Container;
+} // namespace Service::Nvidia::NvCore
+
namespace Service::Nvidia::Devices {
class nvmap final : public nvdevice {
public:
- explicit nvmap(Core::System& system_);
+ explicit nvmap(Core::System& system_, NvCore::Container& container);
~nvmap() override;
+ nvmap(const nvmap&) = delete;
+ nvmap& operator=(const nvmap&) = delete;
+
NvResult Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
std::vector<u8>& output) override;
NvResult Ioctl2(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
@@ -28,31 +36,15 @@ public:
void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override;
- /// Returns the allocated address of an nvmap object given its handle.
- VAddr GetObjectAddress(u32 handle) const;
-
- /// Represents an nvmap object.
- struct Object {
- enum class Status { Created, Allocated };
- u32 id;
- u32 size;
- u32 flags;
- u32 align;
- u8 kind;
- VAddr addr;
- Status status;
- u32 refcount;
- u32 dma_map_addr;
+ enum class HandleParameterType : u32_le {
+ Size = 1,
+ Alignment = 2,
+ Base = 3,
+ Heap = 4,
+ Kind = 5,
+ IsSharedMemMapped = 6
};
- std::shared_ptr<Object> GetObject(u32 handle) const {
- auto itr = handles.find(handle);
- if (itr != handles.end()) {
- return itr->second;
- }
- return {};
- }
-
private:
/// Id to use for the next handle that is created.
u32 next_handle = 0;
@@ -60,9 +52,6 @@ private:
/// Id to use for the next object that is created.
u32 next_id = 0;
- /// Mapping of currently allocated handles to the objects they represent.
- std::unordered_map<u32, std::shared_ptr<Object>> handles;
-
struct IocCreateParams {
// Input
u32_le size{};
@@ -83,11 +72,11 @@ private:
// Input
u32_le handle{};
u32_le heap_mask{};
- u32_le flags{};
+ NvCore::NvMap::Handle::Flags flags{};
u32_le align{};
u8 kind{};
INSERT_PADDING_BYTES(7);
- u64_le addr{};
+ u64_le address{};
};
static_assert(sizeof(IocAllocParams) == 32, "IocAllocParams has wrong size");
@@ -96,14 +85,14 @@ private:
INSERT_PADDING_BYTES(4);
u64_le address{};
u32_le size{};
- u32_le flags{};
+ NvCore::NvMap::Handle::Flags flags{};
};
static_assert(sizeof(IocFreeParams) == 24, "IocFreeParams has wrong size");
struct IocParamParams {
// Input
u32_le handle{};
- u32_le param{};
+ HandleParameterType param{};
// Output
u32_le result{};
};
@@ -117,14 +106,15 @@ private:
};
static_assert(sizeof(IocGetIdParams) == 8, "IocGetIdParams has wrong size");
- u32 CreateObject(u32 size);
-
NvResult IocCreate(const std::vector<u8>& input, std::vector<u8>& output);
NvResult IocAlloc(const std::vector<u8>& input, std::vector<u8>& output);
NvResult IocGetId(const std::vector<u8>& input, std::vector<u8>& output);
NvResult IocFromId(const std::vector<u8>& input, std::vector<u8>& output);
NvResult IocParam(const std::vector<u8>& input, std::vector<u8>& output);
NvResult IocFree(const std::vector<u8>& input, std::vector<u8>& output);
+
+ NvCore::Container& container;
+ NvCore::NvMap& file;
};
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/nvdata.h b/src/core/hle/service/nvdrv/nvdata.h
index 1d00394c8..0e2f47075 100644
--- a/src/core/hle/service/nvdrv/nvdata.h
+++ b/src/core/hle/service/nvdrv/nvdata.h
@@ -1,5 +1,6 @@
-// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
@@ -78,11 +79,15 @@ enum class NvResult : u32 {
ModuleNotPresent = 0xA000E,
};
+// obtained from
+// https://github.com/skyline-emu/skyline/blob/nvdec-dev/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost/ctrl.h#L47
enum class EventState {
- Free = 0,
- Registered = 1,
- Waiting = 2,
- Busy = 3,
+ Available = 0,
+ Waiting = 1,
+ Cancelling = 2,
+ Signalling = 3,
+ Signalled = 4,
+ Cancelled = 5,
};
union Ioctl {
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 756eb7453..9f4c7c99a 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -1,5 +1,6 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
#include <utility>
@@ -7,7 +8,7 @@
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_event.h"
-#include "core/hle/kernel/k_writable_event.h"
+#include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/devices/nvdevice.h"
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
#include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h"
@@ -15,17 +16,31 @@
#include "core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h"
#include "core/hle/service/nvdrv/devices/nvhost_gpu.h"
#include "core/hle/service/nvdrv/devices/nvhost_nvdec.h"
+#include "core/hle/service/nvdrv/devices/nvhost_nvdec_common.h"
#include "core/hle/service/nvdrv/devices/nvhost_nvjpg.h"
#include "core/hle/service/nvdrv/devices/nvhost_vic.h"
#include "core/hle/service/nvdrv/devices/nvmap.h"
#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/hle/service/nvdrv/nvdrv_interface.h"
#include "core/hle/service/nvdrv/nvmemp.h"
-#include "core/hle/service/nvdrv/syncpoint_manager.h"
#include "core/hle/service/nvflinger/nvflinger.h"
+#include "video_core/gpu.h"
namespace Service::Nvidia {
+EventInterface::EventInterface(Module& module_) : module{module_}, guard{}, on_signal{} {}
+
+EventInterface::~EventInterface() = default;
+
+Kernel::KEvent* EventInterface::CreateEvent(std::string name) {
+ Kernel::KEvent* new_event = module.service_context.CreateEvent(std::move(name));
+ return new_event;
+}
+
+void EventInterface::FreeEvent(Kernel::KEvent* event) {
+ module.service_context.CloseEvent(event);
+}
+
void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
Core::System& system) {
auto module_ = std::make_shared<Module>(system);
@@ -38,34 +53,54 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger
}
Module::Module(Core::System& system)
- : syncpoint_manager{system.GPU()}, service_context{system, "nvdrv"} {
- for (u32 i = 0; i < MaxNvEvents; i++) {
- events_interface.events[i].event =
- service_context.CreateEvent(fmt::format("NVDRV::NvEvent_{}", i));
- events_interface.status[i] = EventState::Free;
- events_interface.registered[i] = false;
- }
- auto nvmap_dev = std::make_shared<Devices::nvmap>(system);
- devices["/dev/nvhost-as-gpu"] = std::make_shared<Devices::nvhost_as_gpu>(system, nvmap_dev);
- devices["/dev/nvhost-gpu"] =
- std::make_shared<Devices::nvhost_gpu>(system, nvmap_dev, syncpoint_manager);
- devices["/dev/nvhost-ctrl-gpu"] = std::make_shared<Devices::nvhost_ctrl_gpu>(system);
- devices["/dev/nvmap"] = nvmap_dev;
- devices["/dev/nvdisp_disp0"] = std::make_shared<Devices::nvdisp_disp0>(system, nvmap_dev);
- devices["/dev/nvhost-ctrl"] =
- std::make_shared<Devices::nvhost_ctrl>(system, events_interface, syncpoint_manager);
- devices["/dev/nvhost-nvdec"] =
- std::make_shared<Devices::nvhost_nvdec>(system, nvmap_dev, syncpoint_manager);
- devices["/dev/nvhost-nvjpg"] = std::make_shared<Devices::nvhost_nvjpg>(system);
- devices["/dev/nvhost-vic"] =
- std::make_shared<Devices::nvhost_vic>(system, nvmap_dev, syncpoint_manager);
+ : container{system.Host1x()}, service_context{system, "nvdrv"}, events_interface{*this} {
+ builders["/dev/nvhost-as-gpu"] = [this, &system](DeviceFD fd) {
+ std::shared_ptr<Devices::nvdevice> device =
+ std::make_shared<Devices::nvhost_as_gpu>(system, *this, container);
+ return open_files.emplace(fd, device).first;
+ };
+ builders["/dev/nvhost-gpu"] = [this, &system](DeviceFD fd) {
+ std::shared_ptr<Devices::nvdevice> device =
+ std::make_shared<Devices::nvhost_gpu>(system, events_interface, container);
+ return open_files.emplace(fd, device).first;
+ };
+ builders["/dev/nvhost-ctrl-gpu"] = [this, &system](DeviceFD fd) {
+ std::shared_ptr<Devices::nvdevice> device =
+ std::make_shared<Devices::nvhost_ctrl_gpu>(system, events_interface);
+ return open_files.emplace(fd, device).first;
+ };
+ builders["/dev/nvmap"] = [this, &system](DeviceFD fd) {
+ std::shared_ptr<Devices::nvdevice> device =
+ std::make_shared<Devices::nvmap>(system, container);
+ return open_files.emplace(fd, device).first;
+ };
+ builders["/dev/nvdisp_disp0"] = [this, &system](DeviceFD fd) {
+ std::shared_ptr<Devices::nvdevice> device =
+ std::make_shared<Devices::nvdisp_disp0>(system, container);
+ return open_files.emplace(fd, device).first;
+ };
+ builders["/dev/nvhost-ctrl"] = [this, &system](DeviceFD fd) {
+ std::shared_ptr<Devices::nvdevice> device =
+ std::make_shared<Devices::nvhost_ctrl>(system, events_interface, container);
+ return open_files.emplace(fd, device).first;
+ };
+ builders["/dev/nvhost-nvdec"] = [this, &system](DeviceFD fd) {
+ std::shared_ptr<Devices::nvdevice> device =
+ std::make_shared<Devices::nvhost_nvdec>(system, container);
+ return open_files.emplace(fd, device).first;
+ };
+ builders["/dev/nvhost-nvjpg"] = [this, &system](DeviceFD fd) {
+ std::shared_ptr<Devices::nvdevice> device = std::make_shared<Devices::nvhost_nvjpg>(system);
+ return open_files.emplace(fd, device).first;
+ };
+ builders["/dev/nvhost-vic"] = [this, &system](DeviceFD fd) {
+ std::shared_ptr<Devices::nvdevice> device =
+ std::make_shared<Devices::nvhost_vic>(system, container);
+ return open_files.emplace(fd, device).first;
+ };
}
-Module::~Module() {
- for (u32 i = 0; i < MaxNvEvents; i++) {
- service_context.CloseEvent(events_interface.events[i].event);
- }
-}
+Module::~Module() {}
NvResult Module::VerifyFD(DeviceFD fd) const {
if (fd < 0) {
@@ -82,18 +117,18 @@ NvResult Module::VerifyFD(DeviceFD fd) const {
}
DeviceFD Module::Open(const std::string& device_name) {
- if (devices.find(device_name) == devices.end()) {
+ auto it = builders.find(device_name);
+ if (it == builders.end()) {
LOG_ERROR(Service_NVDRV, "Trying to open unknown device {}", device_name);
return INVALID_NVDRV_FD;
}
- auto device = devices[device_name];
const DeviceFD fd = next_fd++;
+ auto& builder = it->second;
+ auto device = builder(fd)->second;
device->OnOpen(fd);
- open_files[fd] = std::move(device);
-
return fd;
}
@@ -168,22 +203,24 @@ NvResult Module::Close(DeviceFD fd) {
return NvResult::Success;
}
-void Module::SignalSyncpt(const u32 syncpoint_id, const u32 value) {
- for (u32 i = 0; i < MaxNvEvents; i++) {
- if (events_interface.assigned_syncpt[i] == syncpoint_id &&
- events_interface.assigned_value[i] == value) {
- events_interface.LiberateEvent(i);
- events_interface.events[i].event->GetWritableEvent().Signal();
- }
+NvResult Module::QueryEvent(DeviceFD fd, u32 event_id, Kernel::KEvent*& event) {
+ if (fd < 0) {
+ LOG_ERROR(Service_NVDRV, "Invalid DeviceFD={}!", fd);
+ return NvResult::InvalidState;
}
-}
-Kernel::KReadableEvent& Module::GetEvent(const u32 event_id) {
- return events_interface.events[event_id].event->GetReadableEvent();
-}
+ const auto itr = open_files.find(fd);
-Kernel::KWritableEvent& Module::GetEventWriteable(const u32 event_id) {
- return events_interface.events[event_id].event->GetWritableEvent();
+ if (itr == open_files.end()) {
+ LOG_ERROR(Service_NVDRV, "Could not find DeviceFD={}!", fd);
+ return NvResult::NotImplemented;
+ }
+
+ event = itr->second->QueryEvent(event_id);
+ if (!event) {
+ return NvResult::BadParameter;
+ }
+ return NvResult::Success;
}
} // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index c929e5106..f3c81bd88 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -1,16 +1,20 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
+#include <functional>
+#include <list>
#include <memory>
+#include <string>
#include <unordered_map>
#include <vector>
#include "common/common_types.h"
#include "core/hle/service/kernel_helpers.h"
+#include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvdrv/nvdata.h"
-#include "core/hle/service/nvdrv/syncpoint_manager.h"
#include "core/hle/service/nvflinger/ui/fence.h"
#include "core/hle/service/service.h"
@@ -28,81 +32,31 @@ class NVFlinger;
namespace Service::Nvidia {
+namespace NvCore {
+class Container;
class SyncpointManager;
+} // namespace NvCore
namespace Devices {
class nvdevice;
-}
+class nvhost_ctrl;
+} // namespace Devices
-/// Represents an Nvidia event
-struct NvEvent {
- Kernel::KEvent* event{};
- NvFence fence{};
-};
+class Module;
-struct EventInterface {
- // Mask representing currently busy events
- u64 events_mask{};
- // Each kernel event associated to an NV event
- std::array<NvEvent, MaxNvEvents> events;
- // The status of the current NVEvent
- std::array<EventState, MaxNvEvents> status{};
- // Tells if an NVEvent is registered or not
- std::array<bool, MaxNvEvents> registered{};
- // Tells the NVEvent that it has failed.
- std::array<bool, MaxNvEvents> failed{};
- // When an NVEvent is waiting on GPU interrupt, this is the sync_point
- // associated with it.
- std::array<u32, MaxNvEvents> assigned_syncpt{};
- // This is the value of the GPU interrupt for which the NVEvent is waiting
- // for.
- std::array<u32, MaxNvEvents> assigned_value{};
- // Constant to denote an unasigned syncpoint.
- static constexpr u32 unassigned_syncpt = 0xFFFFFFFF;
- std::optional<u32> GetFreeEvent() const {
- u64 mask = events_mask;
- for (u32 i = 0; i < MaxNvEvents; i++) {
- const bool is_free = (mask & 0x1) == 0;
- if (is_free) {
- if (status[i] == EventState::Registered || status[i] == EventState::Free) {
- return {i};
- }
- }
- mask = mask >> 1;
- }
- return std::nullopt;
- }
- void SetEventStatus(const u32 event_id, EventState new_status) {
- EventState old_status = status[event_id];
- if (old_status == new_status) {
- return;
- }
- status[event_id] = new_status;
- if (new_status == EventState::Registered) {
- registered[event_id] = true;
- }
- if (new_status == EventState::Waiting || new_status == EventState::Busy) {
- events_mask |= (1ULL << event_id);
- }
- }
- void RegisterEvent(const u32 event_id) {
- registered[event_id] = true;
- if (status[event_id] == EventState::Free) {
- status[event_id] = EventState::Registered;
- }
- }
- void UnregisterEvent(const u32 event_id) {
- registered[event_id] = false;
- if (status[event_id] == EventState::Registered) {
- status[event_id] = EventState::Free;
- }
- }
- void LiberateEvent(const u32 event_id) {
- status[event_id] = registered[event_id] ? EventState::Registered : EventState::Free;
- events_mask &= ~(1ULL << event_id);
- assigned_syncpt[event_id] = unassigned_syncpt;
- assigned_value[event_id] = 0;
- }
+class EventInterface {
+public:
+ explicit EventInterface(Module& module_);
+ ~EventInterface();
+
+ Kernel::KEvent* CreateEvent(std::string name);
+
+ void FreeEvent(Kernel::KEvent* event);
+
+private:
+ Module& module;
+ std::mutex guard;
+ std::list<Devices::nvhost_ctrl*> on_signal;
};
class Module final {
@@ -112,9 +66,9 @@ public:
/// Returns a pointer to one of the available devices, identified by its name.
template <typename T>
- std::shared_ptr<T> GetDevice(const std::string& name) {
- auto itr = devices.find(name);
- if (itr == devices.end())
+ std::shared_ptr<T> GetDevice(DeviceFD fd) {
+ auto itr = open_files.find(fd);
+ if (itr == open_files.end())
return nullptr;
return std::static_pointer_cast<T>(itr->second);
}
@@ -137,28 +91,27 @@ public:
/// Closes a device file descriptor and returns operation success.
NvResult Close(DeviceFD fd);
- void SignalSyncpt(const u32 syncpoint_id, const u32 value);
-
- Kernel::KReadableEvent& GetEvent(u32 event_id);
-
- Kernel::KWritableEvent& GetEventWriteable(u32 event_id);
+ NvResult QueryEvent(DeviceFD fd, u32 event_id, Kernel::KEvent*& event);
private:
+ friend class EventInterface;
+ friend class Service::NVFlinger::NVFlinger;
+
/// Manages syncpoints on the host
- SyncpointManager syncpoint_manager;
+ NvCore::Container container;
/// Id to use for the next open file descriptor.
DeviceFD next_fd = 1;
+ using FilesContainerType = std::unordered_map<DeviceFD, std::shared_ptr<Devices::nvdevice>>;
/// Mapping of file descriptors to the devices they reference.
- std::unordered_map<DeviceFD, std::shared_ptr<Devices::nvdevice>> open_files;
+ FilesContainerType open_files;
- /// Mapping of device node names to their implementation.
- std::unordered_map<std::string, std::shared_ptr<Devices::nvdevice>> devices;
+ KernelHelpers::ServiceContext service_context;
EventInterface events_interface;
- KernelHelpers::ServiceContext service_context;
+ std::unordered_map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders;
};
/// Registers all NVDRV services with the specified service manager.
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp
index b5a980384..edbdfee43 100644
--- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp
@@ -1,10 +1,12 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
#include <cinttypes>
#include "common/logging/log.h"
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
+#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/service/nvdrv/nvdata.h"
#include "core/hle/service/nvdrv/nvdrv.h"
@@ -12,10 +14,6 @@
namespace Service::Nvidia {
-void NVDRV::SignalGPUInterruptSyncpt(const u32 syncpoint_id, const u32 value) {
- nvdrv->SignalSyncpt(syncpoint_id, value);
-}
-
void NVDRV::Open(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_NVDRV, "called");
IPC::ResponseBuilder rb{ctx, 4};
@@ -164,8 +162,7 @@ void NVDRV::Initialize(Kernel::HLERequestContext& ctx) {
void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto fd = rp.Pop<DeviceFD>();
- const auto event_id = rp.Pop<u32>() & 0x00FF;
- LOG_WARNING(Service_NVDRV, "(STUBBED) called, fd={:X}, event_id={:X}", fd, event_id);
+ const auto event_id = rp.Pop<u32>();
if (!is_initialized) {
ServiceError(ctx, NvResult::NotInitialized);
@@ -173,24 +170,20 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) {
return;
}
- const auto nv_result = nvdrv->VerifyFD(fd);
- if (nv_result != NvResult::Success) {
- LOG_ERROR(Service_NVDRV, "Invalid FD specified DeviceFD={}!", fd);
- ServiceError(ctx, nv_result);
- return;
- }
+ Kernel::KEvent* event = nullptr;
+ NvResult result = nvdrv->QueryEvent(fd, event_id, event);
- if (event_id < MaxNvEvents) {
+ if (result == NvResult::Success) {
IPC::ResponseBuilder rb{ctx, 3, 1};
rb.Push(ResultSuccess);
- auto& event = nvdrv->GetEvent(event_id);
- event.Clear();
- rb.PushCopyObjects(event);
+ auto& readable_event = event->GetReadableEvent();
+ rb.PushCopyObjects(readable_event);
rb.PushEnum(NvResult::Success);
} else {
+ LOG_ERROR(Service_NVDRV, "Invalid event request!");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
- rb.PushEnum(NvResult::BadParameter);
+ rb.PushEnum(result);
}
}
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.h b/src/core/hle/service/nvdrv/nvdrv_interface.h
index cbd37b52b..5ac06ee30 100644
--- a/src/core/hle/service/nvdrv/nvdrv_interface.h
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.h
@@ -7,10 +7,6 @@
#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/hle/service/service.h"
-namespace Kernel {
-class KWritableEvent;
-}
-
namespace Service::Nvidia {
class NVDRV final : public ServiceFramework<NVDRV> {
@@ -18,8 +14,6 @@ public:
explicit NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* name);
~NVDRV() override;
- void SignalGPUInterruptSyncpt(u32 syncpoint_id, u32 value);
-
private:
void Open(Kernel::HLERequestContext& ctx);
void Ioctl1(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/nvdrv/syncpoint_manager.cpp b/src/core/hle/service/nvdrv/syncpoint_manager.cpp
deleted file mode 100644
index a6fa943e8..000000000
--- a/src/core/hle/service/nvdrv/syncpoint_manager.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/assert.h"
-#include "core/hle/service/nvdrv/syncpoint_manager.h"
-#include "video_core/gpu.h"
-
-namespace Service::Nvidia {
-
-SyncpointManager::SyncpointManager(Tegra::GPU& gpu_) : gpu{gpu_} {}
-
-SyncpointManager::~SyncpointManager() = default;
-
-u32 SyncpointManager::RefreshSyncpoint(u32 syncpoint_id) {
- syncpoints[syncpoint_id].min = gpu.GetSyncpointValue(syncpoint_id);
- return GetSyncpointMin(syncpoint_id);
-}
-
-u32 SyncpointManager::AllocateSyncpoint() {
- for (u32 syncpoint_id = 1; syncpoint_id < MaxSyncPoints; syncpoint_id++) {
- if (!syncpoints[syncpoint_id].is_allocated) {
- syncpoints[syncpoint_id].is_allocated = true;
- return syncpoint_id;
- }
- }
- ASSERT_MSG(false, "No more available syncpoints!");
- return {};
-}
-
-u32 SyncpointManager::IncreaseSyncpoint(u32 syncpoint_id, u32 value) {
- for (u32 index = 0; index < value; ++index) {
- syncpoints[syncpoint_id].max.fetch_add(1, std::memory_order_relaxed);
- }
-
- return GetSyncpointMax(syncpoint_id);
-}
-
-} // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvdrv/syncpoint_manager.h b/src/core/hle/service/nvdrv/syncpoint_manager.h
deleted file mode 100644
index 7f080f76e..000000000
--- a/src/core/hle/service/nvdrv/syncpoint_manager.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <array>
-#include <atomic>
-
-#include "common/common_types.h"
-#include "core/hle/service/nvdrv/nvdata.h"
-
-namespace Tegra {
-class GPU;
-}
-
-namespace Service::Nvidia {
-
-class SyncpointManager final {
-public:
- explicit SyncpointManager(Tegra::GPU& gpu_);
- ~SyncpointManager();
-
- /**
- * Returns true if the specified syncpoint is expired for the given value.
- * @param syncpoint_id Syncpoint ID to check.
- * @param value Value to check against the specified syncpoint.
- * @returns True if the specified syncpoint is expired for the given value, otherwise False.
- */
- bool IsSyncpointExpired(u32 syncpoint_id, u32 value) const {
- return (GetSyncpointMax(syncpoint_id) - value) >= (GetSyncpointMin(syncpoint_id) - value);
- }
-
- /**
- * Gets the lower bound for the specified syncpoint.
- * @param syncpoint_id Syncpoint ID to get the lower bound for.
- * @returns The lower bound for the specified syncpoint.
- */
- u32 GetSyncpointMin(u32 syncpoint_id) const {
- return syncpoints.at(syncpoint_id).min.load(std::memory_order_relaxed);
- }
-
- /**
- * Gets the uper bound for the specified syncpoint.
- * @param syncpoint_id Syncpoint ID to get the upper bound for.
- * @returns The upper bound for the specified syncpoint.
- */
- u32 GetSyncpointMax(u32 syncpoint_id) const {
- return syncpoints.at(syncpoint_id).max.load(std::memory_order_relaxed);
- }
-
- /**
- * Refreshes the minimum value for the specified syncpoint.
- * @param syncpoint_id Syncpoint ID to be refreshed.
- * @returns The new syncpoint minimum value.
- */
- u32 RefreshSyncpoint(u32 syncpoint_id);
-
- /**
- * Allocates a new syncoint.
- * @returns The syncpoint ID for the newly allocated syncpoint.
- */
- u32 AllocateSyncpoint();
-
- /**
- * Increases the maximum value for the specified syncpoint.
- * @param syncpoint_id Syncpoint ID to be increased.
- * @param value Value to increase the specified syncpoint by.
- * @returns The new syncpoint maximum value.
- */
- u32 IncreaseSyncpoint(u32 syncpoint_id, u32 value);
-
-private:
- struct Syncpoint {
- std::atomic<u32> min;
- std::atomic<u32> max;
- std::atomic<bool> is_allocated;
- };
-
- std::array<Syncpoint, MaxSyncPoints> syncpoints{};
-
- Tegra::GPU& gpu;
-};
-
-} // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp b/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp
index 4b3d5efd6..1ce67c771 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp
@@ -5,15 +5,18 @@
// https://cs.android.com/android/platform/superproject/+/android-5.1.1_r38:frameworks/native/libs/gui/BufferQueueConsumer.cpp
#include "common/logging/log.h"
+#include "core/hle/service/nvdrv/core/nvmap.h"
#include "core/hle/service/nvflinger/buffer_item.h"
#include "core/hle/service/nvflinger/buffer_queue_consumer.h"
#include "core/hle/service/nvflinger/buffer_queue_core.h"
#include "core/hle/service/nvflinger/producer_listener.h"
+#include "core/hle/service/nvflinger/ui/graphic_buffer.h"
namespace Service::android {
-BufferQueueConsumer::BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_)
- : core{std::move(core_)}, slots{core->slots} {}
+BufferQueueConsumer::BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_,
+ Service::Nvidia::NvCore::NvMap& nvmap_)
+ : core{std::move(core_)}, slots{core->slots}, nvmap(nvmap_) {}
BufferQueueConsumer::~BufferQueueConsumer() = default;
@@ -133,6 +136,8 @@ Status BufferQueueConsumer::ReleaseBuffer(s32 slot, u64 frame_number, const Fenc
slots[slot].buffer_state = BufferState::Free;
+ nvmap.FreeHandle(slots[slot].graphic_buffer->BufferId(), true);
+
listener = core->connected_producer_listener;
LOG_DEBUG(Service_NVFlinger, "releasing slot {}", slot);
diff --git a/src/core/hle/service/nvflinger/buffer_queue_consumer.h b/src/core/hle/service/nvflinger/buffer_queue_consumer.h
index b598c314f..4ec06ca13 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_consumer.h
+++ b/src/core/hle/service/nvflinger/buffer_queue_consumer.h
@@ -13,6 +13,10 @@
#include "core/hle/service/nvflinger/buffer_queue_defs.h"
#include "core/hle/service/nvflinger/status.h"
+namespace Service::Nvidia::NvCore {
+class NvMap;
+} // namespace Service::Nvidia::NvCore
+
namespace Service::android {
class BufferItem;
@@ -21,7 +25,8 @@ class IConsumerListener;
class BufferQueueConsumer final {
public:
- explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_);
+ explicit BufferQueueConsumer(std::shared_ptr<BufferQueueCore> core_,
+ Service::Nvidia::NvCore::NvMap& nvmap_);
~BufferQueueConsumer();
Status AcquireBuffer(BufferItem* out_buffer, std::chrono::nanoseconds expected_present);
@@ -32,6 +37,7 @@ public:
private:
std::shared_ptr<BufferQueueCore> core;
BufferQueueDefs::SlotsType& slots;
+ Service::Nvidia::NvCore::NvMap& nvmap;
};
} // namespace Service::android
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
index 337431488..41ba44b21 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
@@ -11,10 +11,9 @@
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_readable_event.h"
-#include "core/hle/kernel/k_writable_event.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/kernel_helpers.h"
-#include "core/hle/service/nvdrv/nvdrv.h"
+#include "core/hle/service/nvdrv/core/nvmap.h"
#include "core/hle/service/nvflinger/buffer_queue_core.h"
#include "core/hle/service/nvflinger/buffer_queue_producer.h"
#include "core/hle/service/nvflinger/consumer_listener.h"
@@ -26,8 +25,10 @@
namespace Service::android {
BufferQueueProducer::BufferQueueProducer(Service::KernelHelpers::ServiceContext& service_context_,
- std::shared_ptr<BufferQueueCore> buffer_queue_core_)
- : service_context{service_context_}, core{std::move(buffer_queue_core_)}, slots(core->slots) {
+ std::shared_ptr<BufferQueueCore> buffer_queue_core_,
+ Service::Nvidia::NvCore::NvMap& nvmap_)
+ : service_context{service_context_}, core{std::move(buffer_queue_core_)}, slots(core->slots),
+ nvmap(nvmap_) {
buffer_wait_event = service_context.CreateEvent("BufferQueue:WaitEvent");
}
@@ -108,7 +109,7 @@ Status BufferQueueProducer::SetBufferCount(s32 buffer_count) {
core->override_max_buffer_count = buffer_count;
core->SignalDequeueCondition();
- buffer_wait_event->GetWritableEvent().Signal();
+ buffer_wait_event->Signal();
listener = core->consumer_listener;
}
@@ -530,6 +531,8 @@ Status BufferQueueProducer::QueueBuffer(s32 slot, const QueueBufferInput& input,
item.is_droppable = core->dequeue_buffer_cannot_block || async;
item.swap_interval = swap_interval;
+ nvmap.DuplicateHandle(item.graphic_buffer->BufferId(), true);
+
sticky_transform = sticky_transform_;
if (core->queue.empty()) {
@@ -619,7 +622,7 @@ void BufferQueueProducer::CancelBuffer(s32 slot, const Fence& fence) {
slots[slot].fence = fence;
core->SignalDequeueCondition();
- buffer_wait_event->GetWritableEvent().Signal();
+ buffer_wait_event->Signal();
}
Status BufferQueueProducer::Query(NativeWindow what, s32* out_value) {
@@ -739,6 +742,13 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
return Status::NoError;
}
+ // HACK: We are not Android. Remove handle for items in queue, and clear queue.
+ // Allows synchronous destruction of nvmap handles.
+ for (auto& item : core->queue) {
+ nvmap.FreeHandle(item.graphic_buffer->BufferId(), true);
+ }
+ core->queue.clear();
+
switch (api) {
case NativeWindowApi::Egl:
case NativeWindowApi::Cpu:
@@ -749,7 +759,7 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
core->connected_producer_listener = nullptr;
core->connected_api = NativeWindowApi::NoConnectedApi;
core->SignalDequeueCondition();
- buffer_wait_event->GetWritableEvent().Signal();
+ buffer_wait_event->Signal();
listener = core->consumer_listener;
} else {
LOG_ERROR(Service_NVFlinger, "still connected to another api (cur = {} req = {})",
@@ -798,7 +808,7 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
}
core->SignalDequeueCondition();
- buffer_wait_event->GetWritableEvent().Signal();
+ buffer_wait_event->Signal();
return Status::NoError;
}
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.h b/src/core/hle/service/nvflinger/buffer_queue_producer.h
index 42d4722dc..7526bf8ec 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_producer.h
+++ b/src/core/hle/service/nvflinger/buffer_queue_producer.h
@@ -24,13 +24,16 @@ namespace Kernel {
class KernelCore;
class KEvent;
class KReadableEvent;
-class KWritableEvent;
} // namespace Kernel
namespace Service::KernelHelpers {
class ServiceContext;
} // namespace Service::KernelHelpers
+namespace Service::Nvidia::NvCore {
+class NvMap;
+} // namespace Service::Nvidia::NvCore
+
namespace Service::android {
class BufferQueueCore;
@@ -39,7 +42,8 @@ class IProducerListener;
class BufferQueueProducer final : public IBinder {
public:
explicit BufferQueueProducer(Service::KernelHelpers::ServiceContext& service_context_,
- std::shared_ptr<BufferQueueCore> buffer_queue_core_);
+ std::shared_ptr<BufferQueueCore> buffer_queue_core_,
+ Service::Nvidia::NvCore::NvMap& nvmap_);
~BufferQueueProducer();
void Transact(Kernel::HLERequestContext& ctx, android::TransactionId code, u32 flags) override;
@@ -78,6 +82,8 @@ private:
s32 next_callback_ticket{};
s32 current_callback_ticket{};
std::condition_variable_any callback_condition;
+
+ Service::Nvidia::NvCore::NvMap& nvmap;
};
} // namespace Service::android
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 9b382bf56..c3af12c90 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -22,7 +22,10 @@
#include "core/hle/service/nvflinger/ui/graphic_buffer.h"
#include "core/hle/service/vi/display/vi_display.h"
#include "core/hle/service/vi/layer/vi_layer.h"
+#include "core/hle/service/vi/vi_results.h"
#include "video_core/gpu.h"
+#include "video_core/host1x/host1x.h"
+#include "video_core/host1x/syncpoint_manager.h"
namespace Service::NVFlinger {
@@ -30,7 +33,7 @@ constexpr auto frame_ns = std::chrono::nanoseconds{1000000000 / 60};
void NVFlinger::SplitVSync(std::stop_token stop_token) {
system.RegisterHostThread();
- std::string name = "yuzu:VSyncThread";
+ std::string name = "VSyncThread";
MicroProfileOnThreadCreate(name.c_str());
// Cleanup
@@ -99,6 +102,14 @@ NVFlinger::~NVFlinger() {
system.CoreTiming().UnscheduleEvent(single_composition_event, {});
}
+ ShutdownLayers();
+
+ if (nvdrv) {
+ nvdrv->Close(disp_fd);
+ }
+}
+
+void NVFlinger::ShutdownLayers() {
for (auto& display : displays) {
for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) {
display.GetLayer(layer).Core().NotifyShutdown();
@@ -108,6 +119,7 @@ NVFlinger::~NVFlinger() {
void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
nvdrv = std::move(instance);
+ disp_fd = nvdrv->Open("/dev/nvdisp_disp0");
}
std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) {
@@ -126,6 +138,19 @@ std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) {
return itr->GetID();
}
+bool NVFlinger::CloseDisplay(u64 display_id) {
+ const auto lock_guard = Lock();
+ auto* const display = FindDisplay(display_id);
+
+ if (display == nullptr) {
+ return false;
+ }
+
+ display->Reset();
+
+ return true;
+}
+
std::optional<u64> NVFlinger::CreateLayer(u64 display_id) {
const auto lock_guard = Lock();
auto* const display = FindDisplay(display_id);
@@ -141,7 +166,7 @@ std::optional<u64> NVFlinger::CreateLayer(u64 display_id) {
void NVFlinger::CreateLayerAtId(VI::Display& display, u64 layer_id) {
const auto buffer_id = next_buffer_queue_id++;
- display.CreateLayer(layer_id, buffer_id);
+ display.CreateLayer(layer_id, buffer_id, nvdrv->container);
}
void NVFlinger::CloseLayer(u64 layer_id) {
@@ -163,15 +188,15 @@ std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) {
return layer->GetBinderId();
}
-Kernel::KReadableEvent* NVFlinger::FindVsyncEvent(u64 display_id) {
+ResultVal<Kernel::KReadableEvent*> NVFlinger::FindVsyncEvent(u64 display_id) {
const auto lock_guard = Lock();
auto* const display = FindDisplay(display_id);
if (display == nullptr) {
- return nullptr;
+ return VI::ResultNotFound;
}
- return &display->GetVSyncEvent();
+ return display->GetVSyncEvent();
}
VI::Display* NVFlinger::FindDisplay(u64 display_id) {
@@ -261,30 +286,24 @@ void NVFlinger::Compose() {
return; // We are likely shutting down
}
- auto& gpu = system.GPU();
- const auto& multi_fence = buffer.fence;
- guard->unlock();
- for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) {
- const auto& fence = multi_fence.fences[fence_id];
- gpu.WaitFence(fence.id, fence.value);
- }
- guard->lock();
-
- MicroProfileFlip();
-
// Now send the buffer to the GPU for drawing.
// TODO(Subv): Support more than just disp0. The display device selection is probably based
// on which display we're drawing (Default, Internal, External, etc)
- auto nvdisp = nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>("/dev/nvdisp_disp0");
+ auto nvdisp = nvdrv->GetDevice<Nvidia::Devices::nvdisp_disp0>(disp_fd);
ASSERT(nvdisp);
+ guard->unlock();
Common::Rectangle<int> crop_rect{
static_cast<int>(buffer.crop.Left()), static_cast<int>(buffer.crop.Top()),
static_cast<int>(buffer.crop.Right()), static_cast<int>(buffer.crop.Bottom())};
nvdisp->flip(igbp_buffer.BufferId(), igbp_buffer.Offset(), igbp_buffer.ExternalFormat(),
igbp_buffer.Width(), igbp_buffer.Height(), igbp_buffer.Stride(),
- static_cast<android::BufferTransformFlags>(buffer.transform), crop_rect);
+ static_cast<android::BufferTransformFlags>(buffer.transform), crop_rect,
+ buffer.fence.fences, buffer.fence.num_fences);
+
+ MicroProfileFlip();
+ guard->lock();
swap_interval = buffer.swap_interval;
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 044ac6ac8..460bef976 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -11,6 +11,7 @@
#include <vector>
#include "common/common_types.h"
+#include "core/hle/result.h"
#include "core/hle/service/kernel_helpers.h"
namespace Common {
@@ -24,7 +25,6 @@ struct EventType;
namespace Kernel {
class KReadableEvent;
-class KWritableEvent;
} // namespace Kernel
namespace Service::Nvidia {
@@ -48,6 +48,8 @@ public:
explicit NVFlinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_);
~NVFlinger();
+ void ShutdownLayers();
+
/// Sets the NVDrv module instance to use to send buffers to the GPU.
void SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance);
@@ -56,6 +58,11 @@ public:
/// If an invalid display name is provided, then an empty optional is returned.
[[nodiscard]] std::optional<u64> OpenDisplay(std::string_view name);
+ /// Closes the specified display by its ID.
+ ///
+ /// Returns false if an invalid display ID is provided.
+ [[nodiscard]] bool CloseDisplay(u64 display_id);
+
/// Creates a layer on the specified display and returns the layer ID.
///
/// If an invalid display ID is specified, then an empty optional is returned.
@@ -71,8 +78,9 @@ public:
/// Gets the vsync event for the specified display.
///
- /// If an invalid display ID is provided, then nullptr is returned.
- [[nodiscard]] Kernel::KReadableEvent* FindVsyncEvent(u64 display_id);
+ /// If an invalid display ID is provided, then VI::ResultNotFound is returned.
+ /// If the vsync event has already been retrieved, then VI::ResultPermissionDenied is returned.
+ [[nodiscard]] ResultVal<Kernel::KReadableEvent*> FindVsyncEvent(u64 display_id);
/// Performs a composition request to the emulated nvidia GPU and triggers the vsync events when
/// finished.
@@ -114,6 +122,7 @@ private:
void SplitVSync(std::stop_token stop_token);
std::shared_ptr<Nvidia::Module> nvdrv;
+ s32 disp_fd;
std::list<VI::Display> displays;
diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp
index 2c31e9485..1ac97fe31 100644
--- a/src/core/hle/service/ptm/psm.cpp
+++ b/src/core/hle/service/ptm/psm.cpp
@@ -37,19 +37,19 @@ public:
void SignalChargerTypeChanged() {
if (should_signal && should_signal_charger_type) {
- state_change_event->GetWritableEvent().Signal();
+ state_change_event->Signal();
}
}
void SignalPowerSupplyChanged() {
if (should_signal && should_signal_power_supply) {
- state_change_event->GetWritableEvent().Signal();
+ state_change_event->Signal();
}
}
void SignalBatteryVoltageStateChanged() {
if (should_signal && should_signal_battery_voltage) {
- state_change_event->GetWritableEvent().Signal();
+ state_change_event->Signal();
}
}
diff --git a/src/core/hle/service/ptm/ts.cpp b/src/core/hle/service/ptm/ts.cpp
index 65c3f135f..b1a0a5544 100644
--- a/src/core/hle/service/ptm/ts.cpp
+++ b/src/core/hle/service/ptm/ts.cpp
@@ -15,7 +15,7 @@ TS::TS(Core::System& system_) : ServiceFramework{system_, "ts"} {
{0, nullptr, "GetTemperatureRange"},
{1, &TS::GetTemperature, "GetTemperature"},
{2, nullptr, "SetMeasurementMode"},
- {3, nullptr, "GetTemperatureMilliC"},
+ {3, &TS::GetTemperatureMilliC, "GetTemperatureMilliC"},
{4, nullptr, "OpenSession"},
};
// clang-format on
@@ -29,8 +29,6 @@ void TS::GetTemperature(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto location{rp.PopEnum<Location>()};
- LOG_WARNING(Service_HID, "(STUBBED) called. location={}", location);
-
const s32 temperature = location == Location::Internal ? 35 : 20;
IPC::ResponseBuilder rb{ctx, 3};
@@ -38,4 +36,15 @@ void TS::GetTemperature(Kernel::HLERequestContext& ctx) {
rb.Push(temperature);
}
+void TS::GetTemperatureMilliC(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto location{rp.PopEnum<Location>()};
+
+ const s32 temperature = location == Location::Internal ? 35000 : 20000;
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(ResultSuccess);
+ rb.Push(temperature);
+}
+
} // namespace Service::PTM
diff --git a/src/core/hle/service/ptm/ts.h b/src/core/hle/service/ptm/ts.h
index 39a734ef7..39d51847e 100644
--- a/src/core/hle/service/ptm/ts.h
+++ b/src/core/hle/service/ptm/ts.h
@@ -20,6 +20,7 @@ private:
};
void GetTemperature(Kernel::HLERequestContext& ctx);
+ void GetTemperatureMilliC(Kernel::HLERequestContext& ctx);
};
} // namespace Service::PTM
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index dadaf897f..5ab41c0c4 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -99,6 +99,12 @@ ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* se
ServiceFrameworkBase::~ServiceFrameworkBase() {
// Wait for other threads to release access before destroying
const auto guard = LockService();
+
+ if (named_port != nullptr) {
+ named_port->GetClientPort().Close();
+ named_port->GetServerPort().Close();
+ named_port = nullptr;
+ }
}
void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) {
@@ -113,15 +119,16 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager)
Kernel::KClientPort& ServiceFrameworkBase::CreatePort() {
const auto guard = LockService();
- ASSERT(!service_registered);
+ if (named_port == nullptr) {
+ ASSERT(!service_registered);
- auto* port = Kernel::KPort::Create(kernel);
- port->Initialize(max_sessions, false, service_name);
- port->GetServerPort().SetSessionHandler(shared_from_this());
+ named_port = Kernel::KPort::Create(kernel);
+ named_port->Initialize(max_sessions, false, service_name);
- service_registered = true;
+ service_registered = true;
+ }
- return port->GetClientPort();
+ return named_port->GetClientPort();
}
void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) {
@@ -199,7 +206,6 @@ Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session,
switch (ctx.GetCommandType()) {
case IPC::CommandType::Close:
case IPC::CommandType::TIPC_Close: {
- session.Close();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
result = IPC::ERR_REMOTE_PROCESS_DEAD;
@@ -244,6 +250,7 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false);
system.Kernel().RegisterNamedService("sm:", SM::ServiceManager::InterfaceFactory);
+ system.Kernel().RegisterInterfaceForNamedService("sm:", SM::ServiceManager::SessionHandler);
Account::InstallInterfaces(system);
AM::InstallInterfaces(*sm, *nv_flinger, system);
@@ -303,4 +310,8 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
Services::~Services() = default;
+void Services::KillNVNFlinger() {
+ nv_flinger->ShutdownLayers();
+}
+
} // namespace Service
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 5bf197c51..22e2119d7 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -20,6 +20,7 @@ class System;
namespace Kernel {
class HLERequestContext;
class KClientPort;
+class KPort;
class KServerSession;
class ServiceThread;
} // namespace Kernel
@@ -98,6 +99,9 @@ protected:
/// Identifier string used to connect to the service.
std::string service_name;
+ /// Port used by ManageNamedPort.
+ Kernel::KPort* named_port{};
+
private:
template <typename T>
friend class ServiceFramework;
@@ -238,6 +242,8 @@ public:
explicit Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system);
~Services();
+ void KillNVNFlinger();
+
private:
std::unique_ptr<NVFlinger::HosBinderDriverServer> hos_binder_driver_server;
std::unique_ptr<NVFlinger::NVFlinger> nv_flinger;
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index 2a0b812c1..d7cea6aac 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -101,6 +101,81 @@ void SET_SYS::SetColorSetId(Kernel::HLERequestContext& ctx) {
rb.Push(ResultSuccess);
}
+// FIXME: implement support for the real system_settings.ini
+
+template <typename T>
+static std::vector<u8> ToBytes(const T& value) {
+ static_assert(std::is_trivially_copyable_v<T>);
+
+ const auto* begin = reinterpret_cast<const u8*>(&value);
+ const auto* end = begin + sizeof(T);
+
+ return std::vector<u8>(begin, end);
+}
+
+using Settings =
+ std::map<std::string, std::map<std::string, std::vector<u8>, std::less<>>, std::less<>>;
+
+static Settings GetSettings() {
+ Settings ret;
+
+ ret["hbloader"]["applet_heap_size"] = ToBytes(u64{0x0});
+ ret["hbloader"]["applet_heap_reservation_size"] = ToBytes(u64{0x8600000});
+
+ return ret;
+}
+
+void SET_SYS::GetSettingsItemValueSize(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_SET, "called");
+
+ // The category of the setting. This corresponds to the top-level keys of
+ // system_settings.ini.
+ const auto setting_category_buf{ctx.ReadBuffer(0)};
+ const std::string setting_category{setting_category_buf.begin(), setting_category_buf.end()};
+
+ // The name of the setting. This corresponds to the second-level keys of
+ // system_settings.ini.
+ const auto setting_name_buf{ctx.ReadBuffer(1)};
+ const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()};
+
+ auto settings{GetSettings()};
+ u64 response_size{0};
+
+ if (settings.contains(setting_category) && settings[setting_category].contains(setting_name)) {
+ response_size = settings[setting_category][setting_name].size();
+ }
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(response_size == 0 ? ResultUnknown : ResultSuccess);
+ rb.Push(response_size);
+}
+
+void SET_SYS::GetSettingsItemValue(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_SET, "called");
+
+ // The category of the setting. This corresponds to the top-level keys of
+ // system_settings.ini.
+ const auto setting_category_buf{ctx.ReadBuffer(0)};
+ const std::string setting_category{setting_category_buf.begin(), setting_category_buf.end()};
+
+ // The name of the setting. This corresponds to the second-level keys of
+ // system_settings.ini.
+ const auto setting_name_buf{ctx.ReadBuffer(1)};
+ const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()};
+
+ auto settings{GetSettings()};
+ Result response{ResultUnknown};
+
+ if (settings.contains(setting_category) && settings[setting_category].contains(setting_name)) {
+ auto setting_value = settings[setting_category][setting_name];
+ ctx.WriteBuffer(setting_value.data(), setting_value.size());
+ response = ResultSuccess;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(response);
+}
+
SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
// clang-format off
static const FunctionInfo functions[] = {
@@ -138,8 +213,8 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
{32, nullptr, "SetAccountNotificationSettings"},
{35, nullptr, "GetVibrationMasterVolume"},
{36, nullptr, "SetVibrationMasterVolume"},
- {37, nullptr, "GetSettingsItemValueSize"},
- {38, nullptr, "GetSettingsItemValue"},
+ {37, &SET_SYS::GetSettingsItemValueSize, "GetSettingsItemValueSize"},
+ {38, &SET_SYS::GetSettingsItemValue, "GetSettingsItemValue"},
{39, nullptr, "GetTvSettings"},
{40, nullptr, "SetTvSettings"},
{41, nullptr, "GetEdid"},
diff --git a/src/core/hle/service/set/set_sys.h b/src/core/hle/service/set/set_sys.h
index ac97772b7..258ef8c57 100644
--- a/src/core/hle/service/set/set_sys.h
+++ b/src/core/hle/service/set/set_sys.h
@@ -23,6 +23,8 @@ private:
BasicBlack = 1,
};
+ void GetSettingsItemValueSize(Kernel::HLERequestContext& ctx);
+ void GetSettingsItemValue(Kernel::HLERequestContext& ctx);
void GetFirmwareVersion(Kernel::HLERequestContext& ctx);
void GetFirmwareVersion2(Kernel::HLERequestContext& ctx);
void GetColorSetId(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 246c94623..84720094f 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -23,7 +23,13 @@ constexpr Result ERR_INVALID_NAME(ErrorModule::SM, 6);
constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7);
ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {}
-ServiceManager::~ServiceManager() = default;
+
+ServiceManager::~ServiceManager() {
+ for (auto& [name, port] : service_ports) {
+ port->GetClientPort().Close();
+ port->GetServerPort().Close();
+ }
+}
void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) {
controller_interface->InvokeRequest(context);
@@ -43,6 +49,10 @@ Kernel::KClientPort& ServiceManager::InterfaceFactory(ServiceManager& self, Core
return self.sm_interface->CreatePort();
}
+void ServiceManager::SessionHandler(ServiceManager& self, Kernel::KServerPort* server_port) {
+ self.sm_interface->AcceptSession(server_port);
+}
+
Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
Kernel::SessionRequestHandlerPtr handler) {
@@ -53,7 +63,11 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
return ERR_ALREADY_REGISTERED;
}
- registered_services.emplace(std::move(name), handler);
+ auto* port = Kernel::KPort::Create(kernel);
+ port->Initialize(ServerSessionCountMax, false, name);
+
+ service_ports.emplace(name, port);
+ registered_services.emplace(name, handler);
return ResultSuccess;
}
@@ -68,25 +82,20 @@ Result ServiceManager::UnregisterService(const std::string& name) {
}
registered_services.erase(iter);
+ service_ports.erase(name);
+
return ResultSuccess;
}
ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) {
CASCADE_CODE(ValidateServiceName(name));
- auto it = registered_services.find(name);
- if (it == registered_services.end()) {
+ auto it = service_ports.find(name);
+ if (it == service_ports.end()) {
LOG_ERROR(Service_SM, "Server is not registered! service={}", name);
return ERR_SERVICE_NOT_REGISTERED;
}
- auto* port = Kernel::KPort::Create(kernel);
- SCOPE_EXIT({ port->Close(); });
-
- port->Initialize(ServerSessionCountMax, false, name);
- auto handler = it->second;
- port->GetServerPort().SetSessionHandler(std::move(handler));
-
- return port;
+ return it->second;
}
/**
@@ -145,22 +154,20 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
// Find the named port.
auto port_result = service_manager.GetServicePort(name);
- if (port_result.Failed()) {
+ auto service = service_manager.GetService<Kernel::SessionRequestHandler>(name);
+ if (port_result.Failed() || !service) {
LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, port_result.Code().raw);
return port_result.Code();
}
auto& port = port_result.Unwrap();
- SCOPE_EXIT({ port->GetClientPort().Close(); });
-
- kernel.RegisterServerObject(&port->GetServerPort());
// Create a new session.
Kernel::KClientSession* session{};
- if (const auto result = port->GetClientPort().CreateSession(std::addressof(session));
- result.IsError()) {
+ if (const auto result = port->GetClientPort().CreateSession(&session); result.IsError()) {
LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw);
return result;
}
+ service->AcceptSession(&port->GetServerPort());
LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId());
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h
index 878decc6f..02a5dde9e 100644
--- a/src/core/hle/service/sm/sm.h
+++ b/src/core/hle/service/sm/sm.h
@@ -51,6 +51,7 @@ private:
class ServiceManager {
public:
static Kernel::KClientPort& InterfaceFactory(ServiceManager& self, Core::System& system);
+ static void SessionHandler(ServiceManager& self, Kernel::KServerPort* server_port);
explicit ServiceManager(Kernel::KernelCore& kernel_);
~ServiceManager();
@@ -78,6 +79,7 @@ private:
/// Map of registered services, retrieved using GetServicePort.
std::unordered_map<std::string, Kernel::SessionRequestHandlerPtr> registered_services;
+ std::unordered_map<std::string, Kernel::KPort*> service_ports;
/// Kernel context
Kernel::KernelCore& kernel;
diff --git a/src/core/hle/service/sm/sm_controller.cpp b/src/core/hle/service/sm/sm_controller.cpp
index 2a4bd64ab..69e0fe808 100644
--- a/src/core/hle/service/sm/sm_controller.cpp
+++ b/src/core/hle/service/sm/sm_controller.cpp
@@ -15,9 +15,9 @@
namespace Service::SM {
void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) {
- ASSERT_MSG(!ctx.Session()->IsDomain(), "Session is already a domain");
+ ASSERT_MSG(!ctx.GetManager()->IsDomain(), "Session is already a domain");
LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetId());
- ctx.Session()->ConvertToDomain();
+ ctx.GetManager()->ConvertToDomainOnRequestEnd();
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
@@ -27,23 +27,35 @@ void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) {
void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service, "called");
- auto& parent_session = *ctx.Session()->GetParent();
- auto& parent_port = parent_session.GetParent()->GetParent()->GetClientPort();
- auto& session_manager = parent_session.GetServerSession().GetSessionRequestManager();
+ auto& process = *ctx.GetThread().GetOwnerProcess();
+ auto session_manager = ctx.GetManager();
- // Create a session.
- Kernel::KClientSession* session{};
- const Result result = parent_port.CreateSession(std::addressof(session), session_manager);
- if (result.IsError()) {
- LOG_CRITICAL(Service, "CreateSession failed with error 0x{:08X}", result.raw);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(result);
- }
+ // FIXME: this is duplicated from the SVC, it should just call it instead
+ // once this is a proper process
+
+ // Reserve a new session from the process resource limit.
+ Kernel::KScopedResourceReservation session_reservation(&process,
+ Kernel::LimitableResource::Sessions);
+ ASSERT(session_reservation.Succeeded());
+
+ // Create the session.
+ Kernel::KSession* session = Kernel::KSession::Create(system.Kernel());
+ ASSERT(session != nullptr);
+
+ // Initialize the session.
+ session->Initialize(nullptr, "");
+
+ // Commit the session reservation.
+ session_reservation.Commit();
+
+ // Register with manager.
+ session_manager->SessionHandler().RegisterSession(&session->GetServerSession(),
+ session_manager);
// We succeeded.
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
rb.Push(ResultSuccess);
- rb.PushMoveObjects(session);
+ rb.PushMoveObjects(session->GetClientSession());
}
void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index cc679cc81..9e94a462f 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -929,7 +929,7 @@ BSD::BSD(Core::System& system_, const char* name)
proxy_packet_received = room_member->BindOnProxyPacketReceived(
[this](const Network::ProxyPacket& packet) { OnProxyPacketReceived(packet); });
} else {
- LOG_ERROR(Service, "Network isn't initalized");
+ LOG_ERROR(Service, "Network isn't initialized");
}
}
diff --git a/src/core/hle/service/time/system_clock_context_update_callback.cpp b/src/core/hle/service/time/system_clock_context_update_callback.cpp
index a649bed3a..cafc04ee7 100644
--- a/src/core/hle/service/time/system_clock_context_update_callback.cpp
+++ b/src/core/hle/service/time/system_clock_context_update_callback.cpp
@@ -1,7 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-#include "core/hle/kernel/k_writable_event.h"
+#include "core/hle/kernel/k_event.h"
#include "core/hle/service/time/errors.h"
#include "core/hle/service/time/system_clock_context_update_callback.h"
@@ -20,13 +20,13 @@ bool SystemClockContextUpdateCallback::NeedUpdate(const SystemClockContext& valu
}
void SystemClockContextUpdateCallback::RegisterOperationEvent(
- std::shared_ptr<Kernel::KWritableEvent>&& writable_event) {
- operation_event_list.emplace_back(std::move(writable_event));
+ std::shared_ptr<Kernel::KEvent>&& event) {
+ operation_event_list.emplace_back(std::move(event));
}
void SystemClockContextUpdateCallback::BroadcastOperationEvent() {
- for (const auto& writable_event : operation_event_list) {
- writable_event->Signal();
+ for (const auto& event : operation_event_list) {
+ event->Signal();
}
}
diff --git a/src/core/hle/service/time/system_clock_context_update_callback.h b/src/core/hle/service/time/system_clock_context_update_callback.h
index 9c6caf196..bf657acd9 100644
--- a/src/core/hle/service/time/system_clock_context_update_callback.h
+++ b/src/core/hle/service/time/system_clock_context_update_callback.h
@@ -9,7 +9,7 @@
#include "core/hle/service/time/clock_types.h"
namespace Kernel {
-class KWritableEvent;
+class KEvent;
}
namespace Service::Time::Clock {
@@ -24,7 +24,7 @@ public:
bool NeedUpdate(const SystemClockContext& value) const;
- void RegisterOperationEvent(std::shared_ptr<Kernel::KWritableEvent>&& writable_event);
+ void RegisterOperationEvent(std::shared_ptr<Kernel::KEvent>&& event);
void BroadcastOperationEvent();
@@ -37,7 +37,7 @@ protected:
private:
bool has_context{};
- std::vector<std::shared_ptr<Kernel::KWritableEvent>> operation_event_list;
+ std::vector<std::shared_ptr<Kernel::KEvent>> operation_event_list;
};
} // namespace Service::Time::Clock
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp
index b34febb50..8ef74f1f0 100644
--- a/src/core/hle/service/vi/display/vi_display.cpp
+++ b/src/core/hle/service/vi/display/vi_display.cpp
@@ -10,8 +10,8 @@
#include "core/core.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_readable_event.h"
-#include "core/hle/kernel/k_writable_event.h"
#include "core/hle/service/kernel_helpers.h"
+#include "core/hle/service/nvdrv/core/container.h"
#include "core/hle/service/nvflinger/buffer_item_consumer.h"
#include "core/hle/service/nvflinger/buffer_queue_consumer.h"
#include "core/hle/service/nvflinger/buffer_queue_core.h"
@@ -19,6 +19,7 @@
#include "core/hle/service/nvflinger/hos_binder_driver_server.h"
#include "core/hle/service/vi/display/vi_display.h"
#include "core/hle/service/vi/layer/vi_layer.h"
+#include "core/hle/service/vi/vi_results.h"
namespace Service::VI {
@@ -28,11 +29,13 @@ struct BufferQueue {
std::unique_ptr<android::BufferQueueConsumer> consumer;
};
-static BufferQueue CreateBufferQueue(KernelHelpers::ServiceContext& service_context) {
+static BufferQueue CreateBufferQueue(KernelHelpers::ServiceContext& service_context,
+ Service::Nvidia::NvCore::NvMap& nvmap) {
auto buffer_queue_core = std::make_shared<android::BufferQueueCore>();
- return {buffer_queue_core,
- std::make_unique<android::BufferQueueProducer>(service_context, buffer_queue_core),
- std::make_unique<android::BufferQueueConsumer>(buffer_queue_core)};
+ return {
+ buffer_queue_core,
+ std::make_unique<android::BufferQueueProducer>(service_context, buffer_queue_core, nvmap),
+ std::make_unique<android::BufferQueueConsumer>(buffer_queue_core, nvmap)};
}
Display::Display(u64 id, std::string name_,
@@ -55,18 +58,29 @@ const Layer& Display::GetLayer(std::size_t index) const {
return *layers.at(index);
}
-Kernel::KReadableEvent& Display::GetVSyncEvent() {
- return vsync_event->GetReadableEvent();
+ResultVal<Kernel::KReadableEvent*> Display::GetVSyncEvent() {
+ if (got_vsync_event) {
+ return ResultPermissionDenied;
+ }
+
+ got_vsync_event = true;
+
+ return GetVSyncEventUnchecked();
+}
+
+Kernel::KReadableEvent* Display::GetVSyncEventUnchecked() {
+ return &vsync_event->GetReadableEvent();
}
void Display::SignalVSyncEvent() {
- vsync_event->GetWritableEvent().Signal();
+ vsync_event->Signal();
}
-void Display::CreateLayer(u64 layer_id, u32 binder_id) {
+void Display::CreateLayer(u64 layer_id, u32 binder_id,
+ Service::Nvidia::NvCore::Container& nv_core) {
ASSERT_MSG(layers.empty(), "Only one layer is supported per display at the moment");
- auto [core, producer, consumer] = CreateBufferQueue(service_context);
+ auto [core, producer, consumer] = CreateBufferQueue(service_context, nv_core.GetNvMapFile());
auto buffer_item_consumer = std::make_shared<android::BufferItemConsumer>(std::move(consumer));
buffer_item_consumer->Connect(false);
diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h
index 3838bb599..0b65a65da 100644
--- a/src/core/hle/service/vi/display/vi_display.h
+++ b/src/core/hle/service/vi/display/vi_display.h
@@ -9,6 +9,7 @@
#include "common/common_funcs.h"
#include "common/common_types.h"
+#include "core/hle/result.h"
namespace Kernel {
class KEvent;
@@ -26,6 +27,11 @@ namespace Service::NVFlinger {
class HosBinderDriverServer;
}
+namespace Service::Nvidia::NvCore {
+class Container;
+class NvMap;
+} // namespace Service::Nvidia::NvCore
+
namespace Service::VI {
class Layer;
@@ -73,8 +79,16 @@ public:
return layers.size();
}
- /// Gets the readable vsync event.
- Kernel::KReadableEvent& GetVSyncEvent();
+ /**
+ * Gets the internal vsync event.
+ *
+ * @returns The internal Vsync event if it has not yet been retrieved,
+ * VI::ResultPermissionDenied otherwise.
+ */
+ [[nodiscard]] ResultVal<Kernel::KReadableEvent*> GetVSyncEvent();
+
+ /// Gets the internal vsync event.
+ Kernel::KReadableEvent* GetVSyncEventUnchecked();
/// Signals the internal vsync event.
void SignalVSyncEvent();
@@ -84,7 +98,7 @@ public:
/// @param layer_id The ID to assign to the created layer.
/// @param binder_id The ID assigned to the buffer queue.
///
- void CreateLayer(u64 layer_id, u32 binder_id);
+ void CreateLayer(u64 layer_id, u32 binder_id, Service::Nvidia::NvCore::Container& core);
/// Closes and removes a layer from this display with the given ID.
///
@@ -92,6 +106,12 @@ public:
///
void CloseLayer(u64 layer_id);
+ /// Resets the display for a new connection.
+ void Reset() {
+ layers.clear();
+ got_vsync_event = false;
+ }
+
/// Attempts to find a layer with the given ID.
///
/// @param layer_id The layer ID.
@@ -118,6 +138,7 @@ private:
std::vector<std::unique_ptr<Layer>> layers;
Kernel::KEvent* vsync_event{};
+ bool got_vsync_event{false};
};
} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 546879648..bb283e74e 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -29,16 +29,12 @@
#include "core/hle/service/service.h"
#include "core/hle/service/vi/vi.h"
#include "core/hle/service/vi/vi_m.h"
+#include "core/hle/service/vi/vi_results.h"
#include "core/hle/service/vi/vi_s.h"
#include "core/hle/service/vi/vi_u.h"
namespace Service::VI {
-constexpr Result ERR_OPERATION_FAILED{ErrorModule::VI, 1};
-constexpr Result ERR_PERMISSION_DENIED{ErrorModule::VI, 5};
-constexpr Result ERR_UNSUPPORTED{ErrorModule::VI, 6};
-constexpr Result ERR_NOT_FOUND{ErrorModule::VI, 7};
-
struct DisplayInfo {
/// The name of this particular display.
char display_name[0x40]{"Default"};
@@ -62,6 +58,7 @@ static_assert(sizeof(DisplayInfo) == 0x60, "DisplayInfo has wrong size");
class NativeWindow final {
public:
constexpr explicit NativeWindow(u32 id_) : id{id_} {}
+ constexpr explicit NativeWindow(const NativeWindow& other) = default;
private:
const u32 magic = 2;
@@ -327,10 +324,10 @@ private:
IPC::RequestParser rp{ctx};
const u64 display = rp.Pop<u64>();
- LOG_WARNING(Service_VI, "(STUBBED) called. display=0x{:016X}", display);
+ const Result rc = nv_flinger.CloseDisplay(display) ? ResultSuccess : ResultUnknown;
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(rc);
}
void CreateManagedLayer(Kernel::HLERequestContext& ctx) {
@@ -348,7 +345,7 @@ private:
if (!layer_id) {
LOG_ERROR(Service_VI, "Layer not found! display=0x{:016X}", display);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ERR_NOT_FOUND);
+ rb.Push(ResultNotFound);
return;
}
@@ -498,7 +495,7 @@ private:
if (!display_id) {
LOG_ERROR(Service_VI, "Display not found! display_name={}", name);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ERR_NOT_FOUND);
+ rb.Push(ResultNotFound);
return;
}
@@ -511,10 +508,10 @@ private:
IPC::RequestParser rp{ctx};
const u64 display_id = rp.Pop<u64>();
- LOG_WARNING(Service_VI, "(STUBBED) called. display_id=0x{:016X}", display_id);
+ const Result rc = nv_flinger.CloseDisplay(display_id) ? ResultSuccess : ResultUnknown;
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ResultSuccess);
+ rb.Push(rc);
}
// This literally does nothing internally in the actual service itself,
@@ -554,14 +551,14 @@ private:
if (scaling_mode > NintendoScaleMode::PreserveAspectRatio) {
LOG_ERROR(Service_VI, "Invalid scaling mode provided.");
- rb.Push(ERR_OPERATION_FAILED);
+ rb.Push(ResultOperationFailed);
return;
}
if (scaling_mode != NintendoScaleMode::ScaleToWindow &&
scaling_mode != NintendoScaleMode::PreserveAspectRatio) {
LOG_ERROR(Service_VI, "Unsupported scaling mode supplied.");
- rb.Push(ERR_UNSUPPORTED);
+ rb.Push(ResultNotSupported);
return;
}
@@ -594,7 +591,7 @@ private:
if (!display_id) {
LOG_ERROR(Service_VI, "Layer not found! layer_id={}", layer_id);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ERR_NOT_FOUND);
+ rb.Push(ResultNotFound);
return;
}
@@ -602,7 +599,7 @@ private:
if (!buffer_queue_id) {
LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", *display_id);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ERR_NOT_FOUND);
+ rb.Push(ResultNotFound);
return;
}
@@ -640,7 +637,7 @@ private:
if (!layer_id) {
LOG_ERROR(Service_VI, "Layer not found! display_id={}", display_id);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ERR_NOT_FOUND);
+ rb.Push(ResultNotFound);
return;
}
@@ -648,7 +645,7 @@ private:
if (!buffer_queue_id) {
LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", display_id);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ERR_NOT_FOUND);
+ rb.Push(ResultNotFound);
return;
}
@@ -675,19 +672,23 @@ private:
IPC::RequestParser rp{ctx};
const u64 display_id = rp.Pop<u64>();
- LOG_WARNING(Service_VI, "(STUBBED) called. display_id=0x{:016X}", display_id);
+ LOG_DEBUG(Service_VI, "called. display_id={}", display_id);
const auto vsync_event = nv_flinger.FindVsyncEvent(display_id);
- if (!vsync_event) {
- LOG_ERROR(Service_VI, "Vsync event was not found for display_id={}", display_id);
+ if (vsync_event.Failed()) {
+ const auto result = vsync_event.Code();
+ if (result == ResultNotFound) {
+ LOG_ERROR(Service_VI, "Vsync event was not found for display_id={}", display_id);
+ }
+
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ERR_NOT_FOUND);
+ rb.Push(result);
return;
}
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
- rb.PushCopyObjects(vsync_event);
+ rb.PushCopyObjects(*vsync_event);
}
void ConvertScalingMode(Kernel::HLERequestContext& ctx) {
@@ -764,7 +765,7 @@ private:
return ConvertedScaleMode::PreserveAspectRatio;
default:
LOG_ERROR(Service_VI, "Invalid scaling mode specified, mode={}", mode);
- return ERR_OPERATION_FAILED;
+ return ResultOperationFailed;
}
}
@@ -794,7 +795,7 @@ void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System&
if (!IsValidServiceAccess(permission, policy)) {
LOG_ERROR(Service_VI, "Permission denied for policy {}", policy);
IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(ERR_PERMISSION_DENIED);
+ rb.Push(ResultPermissionDenied);
return;
}
diff --git a/src/core/hle/service/vi/vi_results.h b/src/core/hle/service/vi/vi_results.h
new file mode 100644
index 000000000..22bac799f
--- /dev/null
+++ b/src/core/hle/service/vi/vi_results.h
@@ -0,0 +1,15 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/result.h"
+
+namespace Service::VI {
+
+constexpr Result ResultOperationFailed{ErrorModule::VI, 1};
+constexpr Result ResultPermissionDenied{ErrorModule::VI, 5};
+constexpr Result ResultNotSupported{ErrorModule::VI, 6};
+constexpr Result ResultNotFound{ErrorModule::VI, 7};
+
+} // namespace Service::VI
diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp
index cdf38a2a4..447fbffaa 100644
--- a/src/core/internal_network/network.cpp
+++ b/src/core/internal_network/network.cpp
@@ -364,7 +364,7 @@ std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) {
std::vector<WSAPOLLFD> host_pollfds(pollfds.size());
std::transform(pollfds.begin(), pollfds.end(), host_pollfds.begin(), [](PollFD fd) {
WSAPOLLFD result;
- result.fd = fd.socket->fd;
+ result.fd = fd.socket->GetFD();
result.events = TranslatePollEvents(fd.events);
result.revents = 0;
return result;
@@ -430,12 +430,12 @@ std::pair<SocketBase::AcceptResult, Errno> Socket::Accept() {
return {AcceptResult{}, GetAndLogLastError()};
}
- AcceptResult result;
- result.socket = std::make_unique<Socket>();
- result.socket->fd = new_socket;
-
ASSERT(addrlen == sizeof(sockaddr_in));
- result.sockaddr_in = TranslateToSockAddrIn(addr);
+
+ AcceptResult result{
+ .socket = std::make_unique<Socket>(new_socket),
+ .sockaddr_in = TranslateToSockAddrIn(addr),
+ };
return {std::move(result), Errno::SUCCESS};
}
diff --git a/src/core/internal_network/network_interface.cpp b/src/core/internal_network/network_interface.cpp
index 0f0a66160..057fd3661 100644
--- a/src/core/internal_network/network_interface.cpp
+++ b/src/core/internal_network/network_interface.cpp
@@ -188,7 +188,7 @@ std::vector<NetworkInterface> GetAvailableNetworkInterfaces() {
std::optional<NetworkInterface> GetSelectedNetworkInterface() {
const auto& selected_network_interface = Settings::values.network_interface.GetValue();
const auto network_interfaces = Network::GetAvailableNetworkInterfaces();
- if (network_interfaces.size() == 0) {
+ if (network_interfaces.empty()) {
LOG_ERROR(Network, "GetAvailableNetworkInterfaces returned no interfaces");
return std::nullopt;
}
@@ -206,4 +206,14 @@ std::optional<NetworkInterface> GetSelectedNetworkInterface() {
return *res;
}
+void SelectFirstNetworkInterface() {
+ const auto network_interfaces = Network::GetAvailableNetworkInterfaces();
+
+ if (network_interfaces.empty()) {
+ return;
+ }
+
+ Settings::values.network_interface.SetValue(network_interfaces[0].name);
+}
+
} // namespace Network
diff --git a/src/core/internal_network/network_interface.h b/src/core/internal_network/network_interface.h
index 9b98b6b42..175e61b1f 100644
--- a/src/core/internal_network/network_interface.h
+++ b/src/core/internal_network/network_interface.h
@@ -24,5 +24,6 @@ struct NetworkInterface {
std::vector<NetworkInterface> GetAvailableNetworkInterfaces();
std::optional<NetworkInterface> GetSelectedNetworkInterface();
+void SelectFirstNetworkInterface();
} // namespace Network
diff --git a/src/core/internal_network/socket_proxy.cpp b/src/core/internal_network/socket_proxy.cpp
index 0c746bd82..7d5d37bbc 100644
--- a/src/core/internal_network/socket_proxy.cpp
+++ b/src/core/internal_network/socket_proxy.cpp
@@ -6,6 +6,7 @@
#include "common/assert.h"
#include "common/logging/log.h"
+#include "common/zstd_compression.h"
#include "core/internal_network/network.h"
#include "core/internal_network/network_interface.h"
#include "core/internal_network/socket_proxy.h"
@@ -32,8 +33,11 @@ void ProxySocket::HandleProxyPacket(const ProxyPacket& packet) {
return;
}
+ auto decompressed = packet;
+ decompressed.data = Common::Compression::DecompressDataZSTD(packet.data);
+
std::lock_guard guard(packets_mutex);
- received_packets.push(packet);
+ received_packets.push(decompressed);
}
template <typename T>
@@ -185,6 +189,8 @@ std::pair<s32, Errno> ProxySocket::Send(const std::vector<u8>& message, int flag
void ProxySocket::SendPacket(ProxyPacket& packet) {
if (auto room_member = room_network.GetRoomMember().lock()) {
if (room_member->IsConnected()) {
+ packet.data = Common::Compression::CompressDataZSTDDefault(packet.data.data(),
+ packet.data.size());
room_member->SendProxyPacket(packet);
}
}
diff --git a/src/core/internal_network/sockets.h b/src/core/internal_network/sockets.h
index a70429b19..2e328c645 100644
--- a/src/core/internal_network/sockets.h
+++ b/src/core/internal_network/sockets.h
@@ -32,6 +32,10 @@ public:
std::unique_ptr<SocketBase> socket;
SockAddrIn sockaddr_in;
};
+
+ SocketBase() = default;
+ explicit SocketBase(SOCKET fd_) : fd{fd_} {}
+
virtual ~SocketBase() = default;
virtual SocketBase& operator=(const SocketBase&) = delete;
@@ -89,12 +93,19 @@ public:
virtual void HandleProxyPacket(const ProxyPacket& packet) = 0;
+ [[nodiscard]] SOCKET GetFD() const {
+ return fd;
+ }
+
+protected:
SOCKET fd = INVALID_SOCKET;
};
class Socket : public SocketBase {
public:
Socket() = default;
+ explicit Socket(SOCKET fd_) : SocketBase{fd_} {}
+
~Socket() override;
Socket(const Socket&) = delete;
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 104d16efa..f24474ed8 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -244,6 +244,10 @@ static std::unique_ptr<AppLoader> GetFileLoader(Core::System& system, FileSys::V
std::unique_ptr<AppLoader> GetLoader(Core::System& system, FileSys::VirtualFile file,
u64 program_id, std::size_t program_index) {
+ if (!file) {
+ return nullptr;
+ }
+
FileType type = IdentifyFile(file);
const FileType filename_type = GuessFromFilename(file->GetName());
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 34ad7cadd..3ca80c8ff 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -65,7 +65,7 @@ struct Memory::Impl {
return {};
}
- return system.DeviceMemory().GetPointer(paddr) + vaddr;
+ return system.DeviceMemory().GetPointer<u8>(paddr) + vaddr;
}
[[nodiscard]] u8* GetPointerFromDebugMemory(VAddr vaddr) const {
@@ -75,7 +75,7 @@ struct Memory::Impl {
return {};
}
- return system.DeviceMemory().GetPointer(paddr) + vaddr;
+ return system.DeviceMemory().GetPointer<u8>(paddr) + vaddr;
}
u8 Read8(const VAddr addr) {
@@ -233,18 +233,17 @@ struct Memory::Impl {
current_vaddr, src_addr, size);
std::memset(dest_buffer, 0, copy_amount);
},
- [&dest_buffer](const std::size_t copy_amount, const u8* const src_ptr) {
+ [&](const std::size_t copy_amount, const u8* const src_ptr) {
std::memcpy(dest_buffer, src_ptr, copy_amount);
},
- [&system = system, &dest_buffer](const VAddr current_vaddr,
- const std::size_t copy_amount,
- const u8* const host_ptr) {
+ [&](const VAddr current_vaddr, const std::size_t copy_amount,
+ const u8* const host_ptr) {
if constexpr (!UNSAFE) {
system.GPU().FlushRegion(current_vaddr, copy_amount);
}
std::memcpy(dest_buffer, host_ptr, copy_amount);
},
- [&dest_buffer](const std::size_t copy_amount) {
+ [&](const std::size_t copy_amount) {
dest_buffer = static_cast<u8*>(dest_buffer) + copy_amount;
});
}
@@ -267,17 +266,16 @@ struct Memory::Impl {
"Unmapped WriteBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
current_vaddr, dest_addr, size);
},
- [&src_buffer](const std::size_t copy_amount, u8* const dest_ptr) {
+ [&](const std::size_t copy_amount, u8* const dest_ptr) {
std::memcpy(dest_ptr, src_buffer, copy_amount);
},
- [&system = system, &src_buffer](const VAddr current_vaddr,
- const std::size_t copy_amount, u8* const host_ptr) {
+ [&](const VAddr current_vaddr, const std::size_t copy_amount, u8* const host_ptr) {
if constexpr (!UNSAFE) {
system.GPU().InvalidateRegion(current_vaddr, copy_amount);
}
std::memcpy(host_ptr, src_buffer, copy_amount);
},
- [&src_buffer](const std::size_t copy_amount) {
+ [&](const std::size_t copy_amount) {
src_buffer = static_cast<const u8*>(src_buffer) + copy_amount;
});
}
@@ -301,8 +299,7 @@ struct Memory::Impl {
[](const std::size_t copy_amount, u8* const dest_ptr) {
std::memset(dest_ptr, 0, copy_amount);
},
- [&system = system](const VAddr current_vaddr, const std::size_t copy_amount,
- u8* const host_ptr) {
+ [&](const VAddr current_vaddr, const std::size_t copy_amount, u8* const host_ptr) {
system.GPU().InvalidateRegion(current_vaddr, copy_amount);
std::memset(host_ptr, 0, copy_amount);
},
@@ -313,22 +310,20 @@ struct Memory::Impl {
const std::size_t size) {
WalkBlock(
process, dest_addr, size,
- [this, &process, &dest_addr, &src_addr, size](const std::size_t copy_amount,
- const VAddr current_vaddr) {
+ [&](const std::size_t copy_amount, const VAddr current_vaddr) {
LOG_ERROR(HW_Memory,
"Unmapped CopyBlock @ 0x{:016X} (start address = 0x{:016X}, size = {})",
current_vaddr, src_addr, size);
ZeroBlock(process, dest_addr, copy_amount);
},
- [this, &process, &dest_addr](const std::size_t copy_amount, const u8* const src_ptr) {
+ [&](const std::size_t copy_amount, const u8* const src_ptr) {
WriteBlockImpl<false>(process, dest_addr, src_ptr, copy_amount);
},
- [this, &system = system, &process, &dest_addr](
- const VAddr current_vaddr, const std::size_t copy_amount, u8* const host_ptr) {
+ [&](const VAddr current_vaddr, const std::size_t copy_amount, u8* const host_ptr) {
system.GPU().FlushRegion(current_vaddr, copy_amount);
WriteBlockImpl<false>(process, dest_addr, host_ptr, copy_amount);
},
- [&dest_addr, &src_addr](const std::size_t copy_amount) {
+ [&](const std::size_t copy_amount) {
dest_addr += static_cast<VAddr>(copy_amount);
src_addr += static_cast<VAddr>(copy_amount);
});
@@ -499,7 +494,7 @@ struct Memory::Impl {
} else {
while (base != end) {
page_table.pointers[base].Store(
- system.DeviceMemory().GetPointer(target) - (base << YUZU_PAGEBITS), type);
+ system.DeviceMemory().GetPointer<u8>(target) - (base << YUZU_PAGEBITS), type);
page_table.backing_addr[base] = target - (base << YUZU_PAGEBITS);
ASSERT_MSG(page_table.pointers[base].Pointer(),
@@ -551,6 +546,11 @@ struct Memory::Impl {
[]() {});
}
+ [[nodiscard]] u8* GetPointerSilent(const VAddr vaddr) const {
+ return GetPointerImpl(
+ vaddr, []() {}, []() {});
+ }
+
/**
* Reads a particular data type out of memory at the given virtual address.
*
@@ -570,7 +570,7 @@ struct Memory::Impl {
[vaddr]() {
LOG_ERROR(HW_Memory, "Unmapped Read{} @ 0x{:016X}", sizeof(T) * 8, vaddr);
},
- [&system = system, vaddr]() { system.GPU().FlushRegion(vaddr, sizeof(T)); });
+ [&]() { system.GPU().FlushRegion(vaddr, sizeof(T)); });
if (ptr) {
std::memcpy(&result, ptr, sizeof(T));
}
@@ -594,7 +594,7 @@ struct Memory::Impl {
LOG_ERROR(HW_Memory, "Unmapped Write{} @ 0x{:016X} = 0x{:016X}", sizeof(T) * 8,
vaddr, static_cast<u64>(data));
},
- [&system = system, vaddr]() { system.GPU().InvalidateRegion(vaddr, sizeof(T)); });
+ [&]() { system.GPU().InvalidateRegion(vaddr, sizeof(T)); });
if (ptr) {
std::memcpy(ptr, &data, sizeof(T));
}
@@ -608,7 +608,7 @@ struct Memory::Impl {
LOG_ERROR(HW_Memory, "Unmapped WriteExclusive{} @ 0x{:016X} = 0x{:016X}",
sizeof(T) * 8, vaddr, static_cast<u64>(data));
},
- [&system = system, vaddr]() { system.GPU().InvalidateRegion(vaddr, sizeof(T)); });
+ [&]() { system.GPU().InvalidateRegion(vaddr, sizeof(T)); });
if (ptr) {
const auto volatile_pointer = reinterpret_cast<volatile T*>(ptr);
return Common::AtomicCompareAndSwap(volatile_pointer, data, expected);
@@ -623,7 +623,7 @@ struct Memory::Impl {
LOG_ERROR(HW_Memory, "Unmapped WriteExclusive128 @ 0x{:016X} = 0x{:016X}{:016X}",
vaddr, static_cast<u64>(data[1]), static_cast<u64>(data[0]));
},
- [&system = system, vaddr]() { system.GPU().InvalidateRegion(vaddr, sizeof(u128)); });
+ [&]() { system.GPU().InvalidateRegion(vaddr, sizeof(u128)); });
if (ptr) {
const auto volatile_pointer = reinterpret_cast<volatile u64*>(ptr);
return Common::AtomicCompareAndSwap(volatile_pointer, data, expected);
@@ -686,6 +686,10 @@ u8* Memory::GetPointer(VAddr vaddr) {
return impl->GetPointer(vaddr);
}
+u8* Memory::GetPointerSilent(VAddr vaddr) {
+ return impl->GetPointerSilent(vaddr);
+}
+
const u8* Memory::GetPointer(VAddr vaddr) const {
return impl->GetPointer(vaddr);
}
diff --git a/src/core/memory.h b/src/core/memory.h
index a11ff8766..81eac448b 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -114,6 +114,7 @@ public:
* If the address is not valid, nullptr will be returned.
*/
u8* GetPointer(VAddr vaddr);
+ u8* GetPointerSilent(VAddr vaddr);
template <typename T>
T* GetPointer(VAddr vaddr) {
diff --git a/src/dedicated_room/CMakeLists.txt b/src/dedicated_room/CMakeLists.txt
index 1efdbc1f7..2d9731f19 100644
--- a/src/dedicated_room/CMakeLists.txt
+++ b/src/dedicated_room/CMakeLists.txt
@@ -23,5 +23,5 @@ endif()
target_link_libraries(yuzu-room PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
if(UNIX AND NOT APPLE)
- install(TARGETS yuzu-room RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
+ install(TARGETS yuzu-room)
endif()
diff --git a/src/dedicated_room/yuzu_room.cpp b/src/dedicated_room/yuzu_room.cpp
index 7b6deba41..359891883 100644
--- a/src/dedicated_room/yuzu_room.cpp
+++ b/src/dedicated_room/yuzu_room.cpp
@@ -76,7 +76,18 @@ static constexpr char BanListMagic[] = "YuzuRoom-BanList-1";
static constexpr char token_delimiter{':'};
static void PadToken(std::string& token) {
- while (token.size() % 4 != 0) {
+ std::size_t outlen = 0;
+
+ std::array<unsigned char, 512> output{};
+ std::array<unsigned char, 2048> roundtrip{};
+ for (size_t i = 0; i < 3; i++) {
+ mbedtls_base64_decode(output.data(), output.size(), &outlen,
+ reinterpret_cast<const unsigned char*>(token.c_str()),
+ token.length());
+ mbedtls_base64_encode(roundtrip.data(), roundtrip.size(), &outlen, output.data(), outlen);
+ if (memcmp(roundtrip.data(), token.data(), token.size()) == 0) {
+ break;
+ }
token.push_back('=');
}
}
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt
index 4b91b88ce..cc6f0ffc0 100644
--- a/src/input_common/CMakeLists.txt
+++ b/src/input_common/CMakeLists.txt
@@ -18,6 +18,8 @@ add_library(input_common STATIC
drivers/touch_screen.h
drivers/udp_client.cpp
drivers/udp_client.h
+ drivers/virtual_amiibo.cpp
+ drivers/virtual_amiibo.h
helpers/stick_from_buttons.cpp
helpers/stick_from_buttons.h
helpers/touch_from_buttons.cpp
@@ -37,21 +39,14 @@ add_library(input_common STATIC
if (MSVC)
target_compile_options(input_common PRIVATE
/W4
- /WX
/we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data
- /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data
- /we4245 # 'conversion': conversion from 'type1' to 'type2', signed/unsigned mismatch
/we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
+ /we4800 # Implicit conversion from 'type' to bool. Possible information loss
)
else()
target_compile_options(input_common PRIVATE
- -Werror
-Werror=conversion
- -Werror=ignored-qualifiers
- $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter>
- $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable>
- -Werror=unused-variable
)
endif()
diff --git a/src/input_common/drivers/gc_adapter.cpp b/src/input_common/drivers/gc_adapter.cpp
index 27a0ffb0d..826fa2109 100644
--- a/src/input_common/drivers/gc_adapter.cpp
+++ b/src/input_common/drivers/gc_adapter.cpp
@@ -90,7 +90,7 @@ GCAdapter::~GCAdapter() {
void GCAdapter::AdapterInputThread(std::stop_token stop_token) {
LOG_DEBUG(Input, "Input thread started");
- Common::SetCurrentThreadName("yuzu:input:GCAdapter");
+ Common::SetCurrentThreadName("GCAdapter");
s32 payload_size{};
AdapterPayload adapter_payload{};
@@ -214,7 +214,7 @@ void GCAdapter::UpdateStateAxes(std::size_t port, const AdapterPayload& adapter_
}
void GCAdapter::AdapterScanThread(std::stop_token stop_token) {
- Common::SetCurrentThreadName("yuzu:input:ScanGCAdapter");
+ Common::SetCurrentThreadName("ScanGCAdapter");
usb_adapter_handle = nullptr;
pads = {};
while (!stop_token.stop_requested() && !Setup()) {
@@ -324,7 +324,7 @@ bool GCAdapter::GetGCEndpoint(libusb_device* device) {
return true;
}
-Common::Input::VibrationError GCAdapter::SetRumble(
+Common::Input::VibrationError GCAdapter::SetVibration(
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f;
const auto processed_amplitude =
@@ -338,6 +338,10 @@ Common::Input::VibrationError GCAdapter::SetRumble(
return Common::Input::VibrationError::None;
}
+bool GCAdapter::IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {
+ return rumble_enabled;
+}
+
void GCAdapter::UpdateVibrations() {
// Use 8 states to keep the switching between on/off fast enough for
// a human to feel different vibration strenght
diff --git a/src/input_common/drivers/gc_adapter.h b/src/input_common/drivers/gc_adapter.h
index 8682da847..7f81767f7 100644
--- a/src/input_common/drivers/gc_adapter.h
+++ b/src/input_common/drivers/gc_adapter.h
@@ -25,9 +25,11 @@ public:
explicit GCAdapter(std::string input_engine_);
~GCAdapter() override;
- Common::Input::VibrationError SetRumble(
+ Common::Input::VibrationError SetVibration(
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
+ bool IsVibrationEnabled(const PadIdentifier& identifier) override;
+
/// Used for automapping features
std::vector<Common::ParamPackage> GetInputDevices() const override;
ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override;
diff --git a/src/input_common/drivers/mouse.cpp b/src/input_common/drivers/mouse.cpp
index 4909fa8d7..98c3157a8 100644
--- a/src/input_common/drivers/mouse.cpp
+++ b/src/input_common/drivers/mouse.cpp
@@ -37,7 +37,7 @@ Mouse::Mouse(std::string input_engine_) : InputEngine(std::move(input_engine_))
}
void Mouse::UpdateThread(std::stop_token stop_token) {
- Common::SetCurrentThreadName("yuzu:input:Mouse");
+ Common::SetCurrentThreadName("Mouse");
constexpr int update_time = 10;
while (!stop_token.stop_requested()) {
if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) {
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp
index 5cc1ccbd9..45ce588f0 100644
--- a/src/input_common/drivers/sdl_driver.cpp
+++ b/src/input_common/drivers/sdl_driver.cpp
@@ -40,8 +40,8 @@ public:
void EnableMotion() {
if (sdl_controller) {
SDL_GameController* controller = sdl_controller.get();
- has_accel = SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL);
- has_gyro = SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO);
+ has_accel = SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL) == SDL_TRUE;
+ has_gyro = SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO) == SDL_TRUE;
if (has_accel) {
SDL_GameControllerSetSensorEnabled(controller, SDL_SENSOR_ACCEL, SDL_TRUE);
}
@@ -114,6 +114,20 @@ public:
}
return false;
}
+
+ void EnableVibration(bool is_enabled) {
+ has_vibration = is_enabled;
+ is_vibration_tested = true;
+ }
+
+ bool HasVibration() const {
+ return has_vibration;
+ }
+
+ bool IsVibrationTested() const {
+ return is_vibration_tested;
+ }
+
/**
* The Pad identifier of the joystick
*/
@@ -236,6 +250,8 @@ private:
u64 last_motion_update{};
bool has_gyro{false};
bool has_accel{false};
+ bool has_vibration{false};
+ bool is_vibration_tested{false};
BasicMotion motion;
};
@@ -436,7 +452,7 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en
initialized = true;
if (start_thread) {
poll_thread = std::thread([this] {
- Common::SetCurrentThreadName("yuzu:input:SDL");
+ Common::SetCurrentThreadName("SDL_MainLoop");
using namespace std::chrono_literals;
while (initialized) {
SDL_PumpEvents();
@@ -444,7 +460,7 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en
}
});
vibration_thread = std::thread([this] {
- Common::SetCurrentThreadName("yuzu:input:SDL_Vibration");
+ Common::SetCurrentThreadName("SDL_Vibration");
using namespace std::chrono_literals;
while (initialized) {
SendVibrations();
@@ -517,7 +533,7 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const {
return devices;
}
-Common::Input::VibrationError SDLDriver::SetRumble(
+Common::Input::VibrationError SDLDriver::SetVibration(
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
const auto joystick =
GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port));
@@ -546,13 +562,6 @@ Common::Input::VibrationError SDLDriver::SetRumble(
.type = Common::Input::VibrationAmplificationType::Exponential,
};
- if (vibration.type == Common::Input::VibrationAmplificationType::Test) {
- if (!joystick->RumblePlay(new_vibration)) {
- return Common::Input::VibrationError::Unknown;
- }
- return Common::Input::VibrationError::None;
- }
-
vibration_queue.Push(VibrationRequest{
.identifier = identifier,
.vibration = new_vibration,
@@ -561,6 +570,45 @@ Common::Input::VibrationError SDLDriver::SetRumble(
return Common::Input::VibrationError::None;
}
+bool SDLDriver::IsVibrationEnabled(const PadIdentifier& identifier) {
+ const auto joystick =
+ GetSDLJoystickByGUID(identifier.guid.RawString(), static_cast<int>(identifier.port));
+
+ constexpr Common::Input::VibrationStatus test_vibration{
+ .low_amplitude = 1,
+ .low_frequency = 160.0f,
+ .high_amplitude = 1,
+ .high_frequency = 320.0f,
+ .type = Common::Input::VibrationAmplificationType::Exponential,
+ };
+
+ constexpr Common::Input::VibrationStatus zero_vibration{
+ .low_amplitude = 0,
+ .low_frequency = 160.0f,
+ .high_amplitude = 0,
+ .high_frequency = 320.0f,
+ .type = Common::Input::VibrationAmplificationType::Exponential,
+ };
+
+ if (joystick->IsVibrationTested()) {
+ return joystick->HasVibration();
+ }
+
+ // First vibration might fail
+ joystick->RumblePlay(test_vibration);
+
+ // Wait for about 15ms to ensure the controller is ready for the stop command
+ std::this_thread::sleep_for(std::chrono::milliseconds(15));
+
+ if (!joystick->RumblePlay(zero_vibration)) {
+ joystick->EnableVibration(false);
+ return false;
+ }
+
+ joystick->EnableVibration(true);
+ return true;
+}
+
void SDLDriver::SendVibrations() {
while (!vibration_queue.Empty()) {
VibrationRequest request;
diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h
index fc3a44572..d1b4471cf 100644
--- a/src/input_common/drivers/sdl_driver.h
+++ b/src/input_common/drivers/sdl_driver.h
@@ -61,9 +61,11 @@ public:
bool IsStickInverted(const Common::ParamPackage& params) override;
- Common::Input::VibrationError SetRumble(
+ Common::Input::VibrationError SetVibration(
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
+ bool IsVibrationEnabled(const PadIdentifier& identifier) override;
+
private:
struct VibrationRequest {
PadIdentifier identifier;
diff --git a/src/input_common/drivers/virtual_amiibo.cpp b/src/input_common/drivers/virtual_amiibo.cpp
new file mode 100644
index 000000000..0cd5129da
--- /dev/null
+++ b/src/input_common/drivers/virtual_amiibo.cpp
@@ -0,0 +1,101 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include <cstring>
+#include <fmt/format.h>
+
+#include "common/fs/file.h"
+#include "common/fs/fs.h"
+#include "common/fs/path_util.h"
+#include "common/logging/log.h"
+#include "common/settings.h"
+#include "input_common/drivers/virtual_amiibo.h"
+
+namespace InputCommon {
+constexpr PadIdentifier identifier = {
+ .guid = Common::UUID{},
+ .port = 0,
+ .pad = 0,
+};
+
+VirtualAmiibo::VirtualAmiibo(std::string input_engine_) : InputEngine(std::move(input_engine_)) {}
+
+VirtualAmiibo::~VirtualAmiibo() = default;
+
+Common::Input::PollingError VirtualAmiibo::SetPollingMode(
+ [[maybe_unused]] const PadIdentifier& identifier_,
+ const Common::Input::PollingMode polling_mode_) {
+ polling_mode = polling_mode_;
+
+ if (polling_mode == Common::Input::PollingMode::NFC) {
+ if (state == State::Initialized) {
+ state = State::WaitingForAmiibo;
+ }
+ } else {
+ if (state == State::AmiiboIsOpen) {
+ CloseAmiibo();
+ }
+ }
+
+ return Common::Input::PollingError::None;
+}
+
+Common::Input::NfcState VirtualAmiibo::SupportsNfc(
+ [[maybe_unused]] const PadIdentifier& identifier_) const {
+ return Common::Input::NfcState::Success;
+}
+
+Common::Input::NfcState VirtualAmiibo::WriteNfcData(
+ [[maybe_unused]] const PadIdentifier& identifier_, const std::vector<u8>& data) {
+ const Common::FS::IOFile amiibo_file{file_path, Common::FS::FileAccessMode::ReadWrite,
+ Common::FS::FileType::BinaryFile};
+
+ if (!amiibo_file.IsOpen()) {
+ LOG_ERROR(Core, "Amiibo is already on use");
+ return Common::Input::NfcState::WriteFailed;
+ }
+
+ if (!amiibo_file.Write(data)) {
+ LOG_ERROR(Service_NFP, "Error writting to file");
+ return Common::Input::NfcState::WriteFailed;
+ }
+
+ return Common::Input::NfcState::Success;
+}
+
+VirtualAmiibo::State VirtualAmiibo::GetCurrentState() const {
+ return state;
+}
+
+VirtualAmiibo::Info VirtualAmiibo::LoadAmiibo(const std::string& filename) {
+ const Common::FS::IOFile amiibo_file{filename, Common::FS::FileAccessMode::Read,
+ Common::FS::FileType::BinaryFile};
+
+ if (state != State::WaitingForAmiibo) {
+ return Info::WrongDeviceState;
+ }
+
+ if (!amiibo_file.IsOpen()) {
+ return Info::UnableToLoad;
+ }
+
+ amiibo_data.resize(amiibo_size);
+
+ if (amiibo_file.Read(amiibo_data) < amiibo_size_without_password) {
+ return Info::NotAnAmiibo;
+ }
+
+ file_path = filename;
+ state = State::AmiiboIsOpen;
+ SetNfc(identifier, {Common::Input::NfcState::NewAmiibo, amiibo_data});
+ return Info::Success;
+}
+
+VirtualAmiibo::Info VirtualAmiibo::CloseAmiibo() {
+ state = polling_mode == Common::Input::PollingMode::NFC ? State::WaitingForAmiibo
+ : State::Initialized;
+ SetNfc(identifier, {Common::Input::NfcState::AmiiboRemoved, {}});
+ return Info::Success;
+}
+
+} // namespace InputCommon
diff --git a/src/input_common/drivers/virtual_amiibo.h b/src/input_common/drivers/virtual_amiibo.h
new file mode 100644
index 000000000..9eac07544
--- /dev/null
+++ b/src/input_common/drivers/virtual_amiibo.h
@@ -0,0 +1,61 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <array>
+#include <string>
+#include <vector>
+
+#include "common/common_types.h"
+#include "input_common/input_engine.h"
+
+namespace Common::FS {
+class IOFile;
+}
+
+namespace InputCommon {
+
+class VirtualAmiibo final : public InputEngine {
+public:
+ enum class State {
+ Initialized,
+ WaitingForAmiibo,
+ AmiiboIsOpen,
+ };
+
+ enum class Info {
+ Success,
+ UnableToLoad,
+ NotAnAmiibo,
+ WrongDeviceState,
+ Unknown,
+ };
+
+ explicit VirtualAmiibo(std::string input_engine_);
+ ~VirtualAmiibo() override;
+
+ // Sets polling mode to a controller
+ Common::Input::PollingError SetPollingMode(
+ const PadIdentifier& identifier_, const Common::Input::PollingMode polling_mode_) override;
+
+ Common::Input::NfcState SupportsNfc(const PadIdentifier& identifier_) const override;
+
+ Common::Input::NfcState WriteNfcData(const PadIdentifier& identifier_,
+ const std::vector<u8>& data) override;
+
+ State GetCurrentState() const;
+
+ Info LoadAmiibo(const std::string& amiibo_file);
+ Info CloseAmiibo();
+
+private:
+ static constexpr std::size_t amiibo_size = 0x21C;
+ static constexpr std::size_t amiibo_size_without_password = amiibo_size - 0x8;
+
+ std::string file_path{};
+ State state{State::Initialized};
+ std::vector<u8> amiibo_data;
+ Common::Input::PollingMode polling_mode{Common::Input::PollingMode::Pasive};
+};
+} // namespace InputCommon
diff --git a/src/input_common/input_engine.cpp b/src/input_common/input_engine.cpp
index 6ede0e4b0..61cfd0911 100644
--- a/src/input_common/input_engine.cpp
+++ b/src/input_common/input_engine.cpp
@@ -102,6 +102,17 @@ void InputEngine::SetCamera(const PadIdentifier& identifier,
TriggerOnCameraChange(identifier, value);
}
+void InputEngine::SetNfc(const PadIdentifier& identifier, const Common::Input::NfcStatus& value) {
+ {
+ std::scoped_lock lock{mutex};
+ ControllerData& controller = controller_list.at(identifier);
+ if (!configuring) {
+ controller.nfc = value;
+ }
+ }
+ TriggerOnNfcChange(identifier, value);
+}
+
bool InputEngine::GetButton(const PadIdentifier& identifier, int button) const {
std::scoped_lock lock{mutex};
const auto controller_iter = controller_list.find(identifier);
@@ -189,6 +200,18 @@ Common::Input::CameraStatus InputEngine::GetCamera(const PadIdentifier& identifi
return controller.camera;
}
+Common::Input::NfcStatus InputEngine::GetNfc(const PadIdentifier& identifier) const {
+ std::scoped_lock lock{mutex};
+ const auto controller_iter = controller_list.find(identifier);
+ if (controller_iter == controller_list.cend()) {
+ LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(),
+ identifier.pad, identifier.port);
+ return {};
+ }
+ const ControllerData& controller = controller_iter->second;
+ return controller.nfc;
+}
+
void InputEngine::ResetButtonState() {
for (const auto& controller : controller_list) {
for (const auto& button : controller.second.buttons) {
@@ -355,6 +378,20 @@ void InputEngine::TriggerOnCameraChange(const PadIdentifier& identifier,
}
}
+void InputEngine::TriggerOnNfcChange(const PadIdentifier& identifier,
+ [[maybe_unused]] const Common::Input::NfcStatus& value) {
+ std::scoped_lock lock{mutex_callback};
+ for (const auto& poller_pair : callback_list) {
+ const InputIdentifier& poller = poller_pair.second;
+ if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Nfc, 0)) {
+ continue;
+ }
+ if (poller.callback.on_change) {
+ poller.callback.on_change();
+ }
+ }
+}
+
bool InputEngine::IsInputIdentifierEqual(const InputIdentifier& input_identifier,
const PadIdentifier& identifier, EngineInputType type,
int index) const {
diff --git a/src/input_common/input_engine.h b/src/input_common/input_engine.h
index f6b3c4610..d4c264a8e 100644
--- a/src/input_common/input_engine.h
+++ b/src/input_common/input_engine.h
@@ -42,6 +42,7 @@ enum class EngineInputType {
Camera,
HatButton,
Motion,
+ Nfc,
};
namespace std {
@@ -107,12 +108,17 @@ public:
[[maybe_unused]] const Common::Input::LedStatus& led_status) {}
// Sets rumble to a controller
- virtual Common::Input::VibrationError SetRumble(
+ virtual Common::Input::VibrationError SetVibration(
[[maybe_unused]] const PadIdentifier& identifier,
[[maybe_unused]] const Common::Input::VibrationStatus& vibration) {
return Common::Input::VibrationError::NotSupported;
}
+ // Returns true if device supports vibrations
+ virtual bool IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {
+ return false;
+ }
+
// Sets polling mode to a controller
virtual Common::Input::PollingError SetPollingMode(
[[maybe_unused]] const PadIdentifier& identifier,
@@ -127,6 +133,18 @@ public:
return Common::Input::CameraError::NotSupported;
}
+ // Request nfc data from a controller
+ virtual Common::Input::NfcState SupportsNfc(
+ [[maybe_unused]] const PadIdentifier& identifier) const {
+ return Common::Input::NfcState::NotSupported;
+ }
+
+ // Writes data to an nfc tag
+ virtual Common::Input::NfcState WriteNfcData([[maybe_unused]] const PadIdentifier& identifier,
+ [[maybe_unused]] const std::vector<u8>& data) {
+ return Common::Input::NfcState::NotSupported;
+ }
+
// Returns the engine name
[[nodiscard]] const std::string& GetEngineName() const;
@@ -183,6 +201,7 @@ public:
Common::Input::BatteryLevel GetBattery(const PadIdentifier& identifier) const;
BasicMotion GetMotion(const PadIdentifier& identifier, int motion) const;
Common::Input::CameraStatus GetCamera(const PadIdentifier& identifier) const;
+ Common::Input::NfcStatus GetNfc(const PadIdentifier& identifier) const;
int SetCallback(InputIdentifier input_identifier);
void SetMappingCallback(MappingCallback callback);
@@ -195,6 +214,7 @@ protected:
void SetBattery(const PadIdentifier& identifier, Common::Input::BatteryLevel value);
void SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value);
void SetCamera(const PadIdentifier& identifier, const Common::Input::CameraStatus& value);
+ void SetNfc(const PadIdentifier& identifier, const Common::Input::NfcStatus& value);
virtual std::string GetHatButtonName([[maybe_unused]] u8 direction_value) const {
return "Unknown";
@@ -208,6 +228,7 @@ private:
std::unordered_map<int, BasicMotion> motions;
Common::Input::BatteryLevel battery{};
Common::Input::CameraStatus camera{};
+ Common::Input::NfcStatus nfc{};
};
void TriggerOnButtonChange(const PadIdentifier& identifier, int button, bool value);
@@ -218,6 +239,7 @@ private:
const BasicMotion& value);
void TriggerOnCameraChange(const PadIdentifier& identifier,
const Common::Input::CameraStatus& value);
+ void TriggerOnNfcChange(const PadIdentifier& identifier, const Common::Input::NfcStatus& value);
bool IsInputIdentifierEqual(const InputIdentifier& input_identifier,
const PadIdentifier& identifier, EngineInputType type,
diff --git a/src/input_common/input_poller.cpp b/src/input_common/input_poller.cpp
index ffb9b945e..4ac182147 100644
--- a/src/input_common/input_poller.cpp
+++ b/src/input_common/input_poller.cpp
@@ -691,9 +691,56 @@ public:
}
void OnChange() {
+ const auto camera_status = GetStatus();
+
const Common::Input::CallbackStatus status{
.type = Common::Input::InputType::IrSensor,
- .camera_status = GetStatus(),
+ .camera_status = camera_status.format,
+ .raw_data = camera_status.data,
+ };
+
+ TriggerOnChange(status);
+ }
+
+private:
+ const PadIdentifier identifier;
+ int callback_key;
+ InputEngine* input_engine;
+};
+
+class InputFromNfc final : public Common::Input::InputDevice {
+public:
+ explicit InputFromNfc(PadIdentifier identifier_, InputEngine* input_engine_)
+ : identifier(identifier_), input_engine(input_engine_) {
+ UpdateCallback engine_callback{[this]() { OnChange(); }};
+ const InputIdentifier input_identifier{
+ .identifier = identifier,
+ .type = EngineInputType::Nfc,
+ .index = 0,
+ .callback = engine_callback,
+ };
+ callback_key = input_engine->SetCallback(input_identifier);
+ }
+
+ ~InputFromNfc() override {
+ input_engine->DeleteCallback(callback_key);
+ }
+
+ Common::Input::NfcStatus GetStatus() const {
+ return input_engine->GetNfc(identifier);
+ }
+
+ void ForceUpdate() override {
+ OnChange();
+ }
+
+ void OnChange() {
+ const auto nfc_status = GetStatus();
+
+ const Common::Input::CallbackStatus status{
+ .type = Common::Input::InputType::Nfc,
+ .nfc_status = nfc_status.state,
+ .raw_data = nfc_status.data,
};
TriggerOnChange(status);
@@ -716,7 +763,11 @@ public:
Common::Input::VibrationError SetVibration(
const Common::Input::VibrationStatus& vibration_status) override {
- return input_engine->SetRumble(identifier, vibration_status);
+ return input_engine->SetVibration(identifier, vibration_status);
+ }
+
+ bool IsVibrationEnabled() override {
+ return input_engine->IsVibrationEnabled(identifier);
}
Common::Input::PollingError SetPollingMode(Common::Input::PollingMode polling_mode) override {
@@ -727,6 +778,14 @@ public:
return input_engine->SetCameraFormat(identifier, camera_format);
}
+ Common::Input::NfcState SupportsNfc() const override {
+ return input_engine->SupportsNfc(identifier);
+ }
+
+ Common::Input::NfcState WriteNfcData(const std::vector<u8>& data) override {
+ return input_engine->WriteNfcData(identifier, data);
+ }
+
private:
const PadIdentifier identifier;
InputEngine* input_engine;
@@ -742,8 +801,8 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateButtonDevice(
const auto button_id = params.Get("button", 0);
const auto keyboard_key = params.Get("code", 0);
- const auto toggle = params.Get("toggle", false);
- const auto inverted = params.Get("inverted", false);
+ const auto toggle = params.Get("toggle", false) != 0;
+ const auto inverted = params.Get("inverted", false) != 0;
input_engine->PreSetController(identifier);
input_engine->PreSetButton(identifier, button_id);
input_engine->PreSetButton(identifier, keyboard_key);
@@ -765,8 +824,8 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateHatButtonDevice(
const auto button_id = params.Get("hat", 0);
const auto direction = input_engine->GetHatButtonId(params.Get("direction", ""));
- const auto toggle = params.Get("toggle", false);
- const auto inverted = params.Get("inverted", false);
+ const auto toggle = params.Get("toggle", false) != 0;
+ const auto inverted = params.Get("inverted", false) != 0;
input_engine->PreSetController(identifier);
input_engine->PreSetHatButton(identifier, button_id);
@@ -824,7 +883,7 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateAnalogDevice(
.threshold = std::clamp(params.Get("threshold", 0.5f), 0.0f, 1.0f),
.offset = std::clamp(params.Get("offset", 0.0f), -1.0f, 1.0f),
.inverted = params.Get("invert", "+") == "-",
- .toggle = static_cast<bool>(params.Get("toggle", false)),
+ .toggle = params.Get("toggle", false) != 0,
};
input_engine->PreSetController(identifier);
input_engine->PreSetAxis(identifier, axis);
@@ -840,8 +899,8 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTriggerDevice(
};
const auto button = params.Get("button", 0);
- const auto toggle = params.Get("toggle", false);
- const auto inverted = params.Get("inverted", false);
+ const auto toggle = params.Get("toggle", false) != 0;
+ const auto inverted = params.Get("inverted", false) != 0;
const auto axis = params.Get("axis", 0);
const Common::Input::AnalogProperties properties = {
@@ -871,8 +930,8 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateTouchDevice(
};
const auto button = params.Get("button", 0);
- const auto toggle = params.Get("toggle", false);
- const auto inverted = params.Get("inverted", false);
+ const auto toggle = params.Get("toggle", false) != 0;
+ const auto inverted = params.Get("inverted", false) != 0;
const auto axis_x = params.Get("axis_x", 0);
const Common::Input::AnalogProperties properties_x = {
@@ -978,6 +1037,18 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateCameraDevice(
return std::make_unique<InputFromCamera>(identifier, input_engine.get());
}
+std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateNfcDevice(
+ const Common::ParamPackage& params) {
+ const PadIdentifier identifier = {
+ .guid = Common::UUID{params.Get("guid", "")},
+ .port = static_cast<std::size_t>(params.Get("port", 0)),
+ .pad = static_cast<std::size_t>(params.Get("pad", 0)),
+ };
+
+ input_engine->PreSetController(identifier);
+ return std::make_unique<InputFromNfc>(identifier, input_engine.get());
+}
+
InputFactory::InputFactory(std::shared_ptr<InputEngine> input_engine_)
: input_engine(std::move(input_engine_)) {}
@@ -989,6 +1060,9 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::Create(
if (params.Has("camera")) {
return CreateCameraDevice(params);
}
+ if (params.Has("nfc")) {
+ return CreateNfcDevice(params);
+ }
if (params.Has("button") && params.Has("axis")) {
return CreateTriggerDevice(params);
}
diff --git a/src/input_common/input_poller.h b/src/input_common/input_poller.h
index 4410a8415..d7db13ce4 100644
--- a/src/input_common/input_poller.h
+++ b/src/input_common/input_poller.h
@@ -222,6 +222,16 @@ private:
std::unique_ptr<Common::Input::InputDevice> CreateCameraDevice(
const Common::ParamPackage& params);
+ /**
+ * Creates a nfc device from the parameters given.
+ * @param params contains parameters for creating the device:
+ * - "guid": text string for identifying controllers
+ * - "port": port of the connected device
+ * - "pad": slot of the connected controller
+ * @returns a unique input device with the parameters specified
+ */
+ std::unique_ptr<Common::Input::InputDevice> CreateNfcDevice(const Common::ParamPackage& params);
+
std::shared_ptr<InputEngine> input_engine;
};
} // namespace InputCommon
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index 75a57b9fc..b2064ef95 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -11,6 +11,7 @@
#include "input_common/drivers/tas_input.h"
#include "input_common/drivers/touch_screen.h"
#include "input_common/drivers/udp_client.h"
+#include "input_common/drivers/virtual_amiibo.h"
#include "input_common/helpers/stick_from_buttons.h"
#include "input_common/helpers/touch_from_buttons.h"
#include "input_common/input_engine.h"
@@ -87,6 +88,15 @@ struct InputSubsystem::Impl {
Common::Input::RegisterFactory<Common::Input::OutputDevice>(camera->GetEngineName(),
camera_output_factory);
+ virtual_amiibo = std::make_shared<VirtualAmiibo>("virtual_amiibo");
+ virtual_amiibo->SetMappingCallback(mapping_callback);
+ virtual_amiibo_input_factory = std::make_shared<InputFactory>(virtual_amiibo);
+ virtual_amiibo_output_factory = std::make_shared<OutputFactory>(virtual_amiibo);
+ Common::Input::RegisterFactory<Common::Input::InputDevice>(virtual_amiibo->GetEngineName(),
+ virtual_amiibo_input_factory);
+ Common::Input::RegisterFactory<Common::Input::OutputDevice>(virtual_amiibo->GetEngineName(),
+ virtual_amiibo_output_factory);
+
#ifdef HAVE_SDL2
sdl = std::make_shared<SDLDriver>("sdl");
sdl->SetMappingCallback(mapping_callback);
@@ -327,6 +337,7 @@ struct InputSubsystem::Impl {
std::shared_ptr<TasInput::Tas> tas_input;
std::shared_ptr<CemuhookUDP::UDPClient> udp_client;
std::shared_ptr<Camera> camera;
+ std::shared_ptr<VirtualAmiibo> virtual_amiibo;
std::shared_ptr<InputFactory> keyboard_factory;
std::shared_ptr<InputFactory> mouse_factory;
@@ -335,6 +346,7 @@ struct InputSubsystem::Impl {
std::shared_ptr<InputFactory> udp_client_input_factory;
std::shared_ptr<InputFactory> tas_input_factory;
std::shared_ptr<InputFactory> camera_input_factory;
+ std::shared_ptr<InputFactory> virtual_amiibo_input_factory;
std::shared_ptr<OutputFactory> keyboard_output_factory;
std::shared_ptr<OutputFactory> mouse_output_factory;
@@ -342,6 +354,7 @@ struct InputSubsystem::Impl {
std::shared_ptr<OutputFactory> udp_client_output_factory;
std::shared_ptr<OutputFactory> tas_output_factory;
std::shared_ptr<OutputFactory> camera_output_factory;
+ std::shared_ptr<OutputFactory> virtual_amiibo_output_factory;
#ifdef HAVE_SDL2
std::shared_ptr<SDLDriver> sdl;
@@ -402,6 +415,14 @@ const Camera* InputSubsystem::GetCamera() const {
return impl->camera.get();
}
+VirtualAmiibo* InputSubsystem::GetVirtualAmiibo() {
+ return impl->virtual_amiibo.get();
+}
+
+const VirtualAmiibo* InputSubsystem::GetVirtualAmiibo() const {
+ return impl->virtual_amiibo.get();
+}
+
std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const {
return impl->GetInputDevices();
}
diff --git a/src/input_common/main.h b/src/input_common/main.h
index 9a969e747..ced252383 100644
--- a/src/input_common/main.h
+++ b/src/input_common/main.h
@@ -33,6 +33,7 @@ class Camera;
class Keyboard;
class Mouse;
class TouchScreen;
+class VirtualAmiibo;
struct MappingData;
} // namespace InputCommon
@@ -101,6 +102,12 @@ public:
/// Retrieves the underlying camera input device.
[[nodiscard]] const Camera* GetCamera() const;
+ /// Retrieves the underlying virtual amiibo input device.
+ [[nodiscard]] VirtualAmiibo* GetVirtualAmiibo();
+
+ /// Retrieves the underlying virtual amiibo input device.
+ [[nodiscard]] const VirtualAmiibo* GetVirtualAmiibo() const;
+
/**
* Returns all available input devices that this Factory can create a new device with.
* Each returned ParamPackage should have a `display` field used for display, a `engine` field
diff --git a/src/network/network.cpp b/src/network/network.cpp
index 0841e4134..6652a186b 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -15,7 +15,7 @@ RoomNetwork::RoomNetwork() {
bool RoomNetwork::Init() {
if (enet_initialize() != 0) {
- LOG_ERROR(Network, "Error initalizing ENet");
+ LOG_ERROR(Network, "Error initializing ENet");
return false;
}
m_room = std::make_shared<Room>();
diff --git a/src/network/room.cpp b/src/network/room.cpp
index 8c63b255b..dc5dbce7f 100644
--- a/src/network/room.cpp
+++ b/src/network/room.cpp
@@ -212,6 +212,12 @@ public:
void HandleProxyPacket(const ENetEvent* event);
/**
+ * Broadcasts this packet to all members except the sender.
+ * @param event The ENet event containing the data
+ */
+ void HandleLdnPacket(const ENetEvent* event);
+
+ /**
* Extracts a chat entry from a received ENet packet and adds it to the chat queue.
* @param event The ENet event that was received.
*/
@@ -247,6 +253,9 @@ void Room::RoomImpl::ServerLoop() {
case IdProxyPacket:
HandleProxyPacket(&event);
break;
+ case IdLdnPacket:
+ HandleLdnPacket(&event);
+ break;
case IdChatMessage:
HandleChatPacket(&event);
break;
@@ -861,6 +870,60 @@ void Room::RoomImpl::HandleProxyPacket(const ENetEvent* event) {
enet_host_flush(server);
}
+void Room::RoomImpl::HandleLdnPacket(const ENetEvent* event) {
+ Packet in_packet;
+ in_packet.Append(event->packet->data, event->packet->dataLength);
+
+ in_packet.IgnoreBytes(sizeof(u8)); // Message type
+
+ in_packet.IgnoreBytes(sizeof(u8)); // LAN packet type
+ in_packet.IgnoreBytes(sizeof(IPv4Address)); // Local IP
+
+ IPv4Address remote_ip;
+ in_packet.Read(remote_ip); // Remote IP
+
+ bool broadcast;
+ in_packet.Read(broadcast); // Broadcast
+
+ Packet out_packet;
+ out_packet.Append(event->packet->data, event->packet->dataLength);
+ ENetPacket* enet_packet = enet_packet_create(out_packet.GetData(), out_packet.GetDataSize(),
+ ENET_PACKET_FLAG_RELIABLE);
+
+ const auto& destination_address = remote_ip;
+ if (broadcast) { // Send the data to everyone except the sender
+ std::lock_guard lock(member_mutex);
+ bool sent_packet = false;
+ for (const auto& member : members) {
+ if (member.peer != event->peer) {
+ sent_packet = true;
+ enet_peer_send(member.peer, 0, enet_packet);
+ }
+ }
+
+ if (!sent_packet) {
+ enet_packet_destroy(enet_packet);
+ }
+ } else {
+ std::lock_guard lock(member_mutex);
+ auto member = std::find_if(members.begin(), members.end(),
+ [destination_address](const Member& member_entry) -> bool {
+ return member_entry.fake_ip == destination_address;
+ });
+ if (member != members.end()) {
+ enet_peer_send(member->peer, 0, enet_packet);
+ } else {
+ LOG_ERROR(Network,
+ "Attempting to send to unknown IP address: "
+ "{}.{}.{}.{}",
+ destination_address[0], destination_address[1], destination_address[2],
+ destination_address[3]);
+ enet_packet_destroy(enet_packet);
+ }
+ }
+ enet_host_flush(server);
+}
+
void Room::RoomImpl::HandleChatPacket(const ENetEvent* event) {
Packet in_packet;
in_packet.Append(event->packet->data, event->packet->dataLength);
diff --git a/src/network/room.h b/src/network/room.h
index c2a4b1a70..edbd3ecfb 100644
--- a/src/network/room.h
+++ b/src/network/room.h
@@ -40,6 +40,7 @@ enum RoomMessageTypes : u8 {
IdRoomInformation,
IdSetGameInfo,
IdProxyPacket,
+ IdLdnPacket,
IdChatMessage,
IdNameCollision,
IdIpCollision,
diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp
index 06818af78..b94cb24ad 100644
--- a/src/network/room_member.cpp
+++ b/src/network/room_member.cpp
@@ -58,6 +58,7 @@ public:
private:
CallbackSet<ProxyPacket> callback_set_proxy_packet;
+ CallbackSet<LDNPacket> callback_set_ldn_packet;
CallbackSet<ChatEntry> callback_set_chat_messages;
CallbackSet<StatusMessageEntry> callback_set_status_messages;
CallbackSet<RoomInformation> callback_set_room_information;
@@ -108,6 +109,12 @@ public:
void HandleProxyPackets(const ENetEvent* event);
/**
+ * Extracts an LdnPacket from a received ENet packet.
+ * @param event The ENet event that was received.
+ */
+ void HandleLdnPackets(const ENetEvent* event);
+
+ /**
* Extracts a chat entry from a received ENet packet and adds it to the chat queue.
* @param event The ENet event that was received.
*/
@@ -166,6 +173,9 @@ void RoomMember::RoomMemberImpl::MemberLoop() {
case IdProxyPacket:
HandleProxyPackets(&event);
break;
+ case IdLdnPacket:
+ HandleLdnPackets(&event);
+ break;
case IdChatMessage:
HandleChatPacket(&event);
break;
@@ -372,6 +382,27 @@ void RoomMember::RoomMemberImpl::HandleProxyPackets(const ENetEvent* event) {
Invoke<ProxyPacket>(proxy_packet);
}
+void RoomMember::RoomMemberImpl::HandleLdnPackets(const ENetEvent* event) {
+ LDNPacket ldn_packet{};
+ Packet packet;
+ packet.Append(event->packet->data, event->packet->dataLength);
+
+ // Ignore the first byte, which is the message id.
+ packet.IgnoreBytes(sizeof(u8)); // Ignore the message type
+
+ u8 packet_type;
+ packet.Read(packet_type);
+ ldn_packet.type = static_cast<LDNPacketType>(packet_type);
+
+ packet.Read(ldn_packet.local_ip);
+ packet.Read(ldn_packet.remote_ip);
+ packet.Read(ldn_packet.broadcast);
+
+ packet.Read(ldn_packet.data);
+
+ Invoke<LDNPacket>(ldn_packet);
+}
+
void RoomMember::RoomMemberImpl::HandleChatPacket(const ENetEvent* event) {
Packet packet;
packet.Append(event->packet->data, event->packet->dataLength);
@@ -450,6 +481,11 @@ RoomMember::RoomMemberImpl::CallbackSet<ProxyPacket>& RoomMember::RoomMemberImpl
}
template <>
+RoomMember::RoomMemberImpl::CallbackSet<LDNPacket>& RoomMember::RoomMemberImpl::Callbacks::Get() {
+ return callback_set_ldn_packet;
+}
+
+template <>
RoomMember::RoomMemberImpl::CallbackSet<RoomMember::State>&
RoomMember::RoomMemberImpl::Callbacks::Get() {
return callback_set_state;
@@ -607,6 +643,21 @@ void RoomMember::SendProxyPacket(const ProxyPacket& proxy_packet) {
room_member_impl->Send(std::move(packet));
}
+void RoomMember::SendLdnPacket(const LDNPacket& ldn_packet) {
+ Packet packet;
+ packet.Write(static_cast<u8>(IdLdnPacket));
+
+ packet.Write(static_cast<u8>(ldn_packet.type));
+
+ packet.Write(ldn_packet.local_ip);
+ packet.Write(ldn_packet.remote_ip);
+ packet.Write(ldn_packet.broadcast);
+
+ packet.Write(ldn_packet.data);
+
+ room_member_impl->Send(std::move(packet));
+}
+
void RoomMember::SendChatMessage(const std::string& message) {
Packet packet;
packet.Write(static_cast<u8>(IdChatMessage));
@@ -663,6 +714,11 @@ RoomMember::CallbackHandle<ProxyPacket> RoomMember::BindOnProxyPacketReceived(
return room_member_impl->Bind(callback);
}
+RoomMember::CallbackHandle<LDNPacket> RoomMember::BindOnLdnPacketReceived(
+ std::function<void(const LDNPacket&)> callback) {
+ return room_member_impl->Bind(std::move(callback));
+}
+
RoomMember::CallbackHandle<RoomInformation> RoomMember::BindOnRoomInformationChanged(
std::function<void(const RoomInformation&)> callback) {
return room_member_impl->Bind(callback);
@@ -699,6 +755,7 @@ void RoomMember::Leave() {
}
template void RoomMember::Unbind(CallbackHandle<ProxyPacket>);
+template void RoomMember::Unbind(CallbackHandle<LDNPacket>);
template void RoomMember::Unbind(CallbackHandle<RoomMember::State>);
template void RoomMember::Unbind(CallbackHandle<RoomMember::Error>);
template void RoomMember::Unbind(CallbackHandle<RoomInformation>);
diff --git a/src/network/room_member.h b/src/network/room_member.h
index f578f7f6a..0d6417294 100644
--- a/src/network/room_member.h
+++ b/src/network/room_member.h
@@ -17,7 +17,24 @@ namespace Network {
using AnnounceMultiplayerRoom::GameInfo;
using AnnounceMultiplayerRoom::RoomInformation;
-/// Information about the received WiFi packets.
+enum class LDNPacketType : u8 {
+ Scan,
+ ScanResp,
+ Connect,
+ SyncNetwork,
+ Disconnect,
+ DestroyNetwork,
+};
+
+struct LDNPacket {
+ LDNPacketType type;
+ IPv4Address local_ip;
+ IPv4Address remote_ip;
+ bool broadcast;
+ std::vector<u8> data;
+};
+
+/// Information about the received proxy packets.
struct ProxyPacket {
SockAddrIn local_endpoint;
SockAddrIn remote_endpoint;
@@ -152,6 +169,12 @@ public:
void SendProxyPacket(const ProxyPacket& packet);
/**
+ * Sends an LDN packet to the room.
+ * @param packet The WiFi packet to send.
+ */
+ void SendLdnPacket(const LDNPacket& packet);
+
+ /**
* Sends a chat message to the room.
* @param message The contents of the message.
*/
@@ -205,6 +228,16 @@ public:
std::function<void(const ProxyPacket&)> callback);
/**
+ * Binds a function to an event that will be triggered every time an LDNPacket is received.
+ * The function wil be called everytime the event is triggered.
+ * The callback function must not bind or unbind a function. Doing so will cause a deadlock
+ * @param callback The function to call
+ * @return A handle used for removing the function from the registered list
+ */
+ CallbackHandle<LDNPacket> BindOnLdnPacketReceived(
+ std::function<void(const LDNPacket&)> callback);
+
+ /**
* Binds a function to an event that will be triggered every time the RoomInformation changes.
* The function wil be called every time the event is triggered.
* The callback function must not bind or unbind a function. Doing so will cause a deadlock
diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt
index 189e5cb17..545d69c7e 100644
--- a/src/shader_recompiler/CMakeLists.txt
+++ b/src/shader_recompiler/CMakeLists.txt
@@ -242,24 +242,14 @@ target_link_libraries(shader_recompiler PUBLIC common fmt::fmt sirit)
if (MSVC)
target_compile_options(shader_recompiler PRIVATE
/W4
- /WX
- /we4018 # 'expression' : signed/unsigned mismatch
- /we4244 # 'argument' : conversion from 'type1' to 'type2', possible loss of data (floating-point)
- /we4245 # 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch
+
+ /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data
/we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
- /we4267 # 'var' : conversion from 'size_t' to 'type', possible loss of data
- /we4305 # 'context' : truncation from 'type1' to 'type2'
/we4800 # Implicit conversion from 'type' to bool. Possible information loss
- /we4826 # Conversion from 'type1' to 'type2' is sign-extended. This may cause unexpected runtime behavior.
)
else()
target_compile_options(shader_recompiler PRIVATE
- -Werror
-Werror=conversion
- -Werror=ignored-qualifiers
- $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter>
- $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable>
- -Werror=unused-variable
# Bracket depth determines maximum size of a fold expression in Clang since 9c9974c3ccb6.
# And this in turns limits the size of a std::array.
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
index 1419207e8..3b0176bf6 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
@@ -175,7 +175,7 @@ bool IsReference(IR::Inst& inst) {
}
void PrecolorInst(IR::Inst& phi) {
- // Insert phi moves before references to avoid overwritting other phis
+ // Insert phi moves before references to avoid overwriting other phis
const size_t num_args{phi.NumArgs()};
for (size_t i = 0; i < num_args; ++i) {
IR::Block& phi_block{*phi.PhiBlock(i)};
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
index ee0b0f53d..0a7d42dda 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_context_get_set.cpp
@@ -13,9 +13,6 @@ namespace Shader::Backend::GLASM {
namespace {
void GetCbuf(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU32 offset,
std::string_view size) {
- if (!binding.IsImmediate()) {
- throw NotImplementedException("Indirect constant buffer loading");
- }
const Register ret{ctx.reg_alloc.Define(inst)};
if (offset.type == Type::U32) {
// Avoid reading arrays out of bounds, matching hardware's behavior
@@ -24,7 +21,27 @@ void GetCbuf(EmitContext& ctx, IR::Inst& inst, const IR::Value& binding, ScalarU
return;
}
}
- ctx.Add("LDC.{} {},c{}[{}];", size, ret, binding.U32(), offset);
+
+ if (binding.IsImmediate()) {
+ ctx.Add("LDC.{} {},c{}[{}];", size, ret, binding.U32(), offset);
+ return;
+ }
+
+ const ScalarU32 idx{ctx.reg_alloc.Consume(binding)};
+ for (u32 i = 0; i < Info::MAX_INDIRECT_CBUFS; i++) {
+ ctx.Add("SEQ.S.CC RC.x,{},{};"
+ "IF NE.x;"
+ "LDC.{} {},c{}[{}];",
+ idx, i, size, ret, i, offset);
+
+ if (i != Info::MAX_INDIRECT_CBUFS - 1) {
+ ctx.Add("ELSE;");
+ }
+ }
+
+ for (u32 i = 0; i < Info::MAX_INDIRECT_CBUFS; i++) {
+ ctx.Add("ENDIF;");
+ }
}
bool IsInputArray(Stage stage) {
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
index 7094d8e42..1f4ffdd62 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
@@ -5,10 +5,6 @@
#include "shader_recompiler/backend/glasm/glasm_emit_context.h"
#include "shader_recompiler/frontend/ir/value.h"
-#ifdef _MSC_VER
-#pragma warning(disable : 4100)
-#endif
-
namespace Shader::Backend::GLASM {
#define NotImplemented() throw NotImplementedException("GLASM instruction {}", __LINE__)
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl.cpp b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
index 76c18e488..e8a4390f6 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl.cpp
@@ -101,7 +101,7 @@ bool IsReference(IR::Inst& inst) {
}
void PrecolorInst(IR::Inst& phi) {
- // Insert phi moves before references to avoid overwritting other phis
+ // Insert phi moves before references to avoid overwriting other phis
const size_t num_args{phi.NumArgs()};
for (size_t i = 0; i < num_args; ++i) {
IR::Block& phi_block{*phi.PhiBlock(i)};
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
index b03a8ba1e..9f1ed95a4 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_not_implemented.cpp
@@ -7,10 +7,6 @@
#include "shader_recompiler/backend/glsl/glsl_emit_context.h"
#include "shader_recompiler/frontend/ir/value.h"
-#ifdef _MSC_VER
-#pragma warning(disable : 4100)
-#endif
-
namespace Shader::Backend::GLSL {
void EmitGetRegister(EmitContext& ctx) {
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp
index 468782eb1..84417980b 100644
--- a/src/shader_recompiler/frontend/ir/microinstruction.cpp
+++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp
@@ -325,11 +325,6 @@ void Inst::AddPhiOperand(Block* predecessor, const Value& value) {
phi_args.emplace_back(predecessor, value);
}
-void Inst::ErasePhiOperand(size_t index) {
- const auto operand_it{phi_args.begin() + static_cast<ptrdiff_t>(index)};
- phi_args.erase(operand_it);
-}
-
void Inst::OrderPhiArgs() {
if (op != Opcode::Phi) {
throw LogicError("{} is not a Phi instruction", op);
diff --git a/src/shader_recompiler/frontend/ir/value.h b/src/shader_recompiler/frontend/ir/value.h
index 1a2e4ccb6..6a673ca05 100644
--- a/src/shader_recompiler/frontend/ir/value.h
+++ b/src/shader_recompiler/frontend/ir/value.h
@@ -178,13 +178,9 @@ public:
/// Get a pointer to the block of a phi argument.
[[nodiscard]] Block* PhiBlock(size_t index) const;
-
/// Add phi operand to a phi instruction.
void AddPhiOperand(Block* predecessor, const Value& value);
- // Erase the phi operand at the given index.
- void ErasePhiOperand(size_t index);
-
/// Orders the Phi arguments from farthest away to nearest.
void OrderPhiArgs();
diff --git a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp
index 578bc8c1b..ce42475d4 100644
--- a/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp
+++ b/src/shader_recompiler/frontend/maxwell/structured_control_flow.cpp
@@ -964,9 +964,9 @@ private:
demote_endif_node.type = Type::EndIf;
demote_endif_node.data.end_if.merge = return_block_it->data.block;
- asl.insert(return_block_it, demote_endif_node);
- asl.insert(return_block_it, demote_node);
- asl.insert(return_block_it, demote_if_node);
+ const auto next_it_1 = asl.insert(return_block_it, demote_endif_node);
+ const auto next_it_2 = asl.insert(next_it_1, demote_node);
+ asl.insert(next_it_2, demote_if_node);
}
ObjectPool<Statement>& stmt_pool;
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
index dafb9deee..b7162f719 100644
--- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
@@ -137,28 +137,35 @@ bool IsLegacyAttribute(IR::Attribute attribute) {
}
std::map<IR::Attribute, IR::Attribute> GenerateLegacyToGenericMappings(
- const VaryingState& state, std::queue<IR::Attribute> ununsed_generics) {
+ const VaryingState& state, std::queue<IR::Attribute> unused_generics,
+ const std::map<IR::Attribute, IR::Attribute>& previous_stage_mapping) {
std::map<IR::Attribute, IR::Attribute> mapping;
+ auto update_mapping = [&mapping, &unused_generics, previous_stage_mapping](IR::Attribute attr,
+ size_t count) {
+ if (previous_stage_mapping.find(attr) != previous_stage_mapping.end()) {
+ for (size_t i = 0; i < count; ++i) {
+ mapping.insert({attr + i, previous_stage_mapping.at(attr + i)});
+ }
+ } else {
+ for (size_t i = 0; i < count; ++i) {
+ mapping.insert({attr + i, unused_generics.front() + i});
+ }
+ unused_generics.pop();
+ }
+ };
for (size_t index = 0; index < 4; ++index) {
auto attr = IR::Attribute::ColorFrontDiffuseR + index * 4;
if (state.AnyComponent(attr)) {
- for (size_t i = 0; i < 4; ++i) {
- mapping.insert({attr + i, ununsed_generics.front() + i});
- }
- ununsed_generics.pop();
+ update_mapping(attr, 4);
}
}
if (state[IR::Attribute::FogCoordinate]) {
- mapping.insert({IR::Attribute::FogCoordinate, ununsed_generics.front()});
- ununsed_generics.pop();
+ update_mapping(IR::Attribute::FogCoordinate, 1);
}
for (size_t index = 0; index < IR::NUM_FIXEDFNCTEXTURE; ++index) {
auto attr = IR::Attribute::FixedFncTexture0S + index * 4;
if (state.AnyComponent(attr)) {
- for (size_t i = 0; i < 4; ++i) {
- mapping.insert({attr + i, ununsed_generics.front() + i});
- }
- ununsed_generics.pop();
+ update_mapping(attr, 4);
}
}
return mapping;
@@ -267,21 +274,22 @@ IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b
void ConvertLegacyToGeneric(IR::Program& program, const Shader::RuntimeInfo& runtime_info) {
auto& stores = program.info.stores;
if (stores.Legacy()) {
- std::queue<IR::Attribute> ununsed_output_generics{};
+ std::queue<IR::Attribute> unused_output_generics{};
for (size_t index = 0; index < IR::NUM_GENERICS; ++index) {
if (!stores.Generic(index)) {
- ununsed_output_generics.push(IR::Attribute::Generic0X + index * 4);
+ unused_output_generics.push(IR::Attribute::Generic0X + index * 4);
}
}
- auto mappings = GenerateLegacyToGenericMappings(stores, ununsed_output_generics);
+ program.info.legacy_stores_mapping =
+ GenerateLegacyToGenericMappings(stores, unused_output_generics, {});
for (IR::Block* const block : program.post_order_blocks) {
for (IR::Inst& inst : block->Instructions()) {
switch (inst.GetOpcode()) {
case IR::Opcode::SetAttribute: {
const auto attr = inst.Arg(0).Attribute();
if (IsLegacyAttribute(attr)) {
- stores.Set(mappings[attr], true);
- inst.SetArg(0, Shader::IR::Value(mappings[attr]));
+ stores.Set(program.info.legacy_stores_mapping[attr], true);
+ inst.SetArg(0, Shader::IR::Value(program.info.legacy_stores_mapping[attr]));
}
break;
}
@@ -294,15 +302,16 @@ void ConvertLegacyToGeneric(IR::Program& program, const Shader::RuntimeInfo& run
auto& loads = program.info.loads;
if (loads.Legacy()) {
- std::queue<IR::Attribute> ununsed_input_generics{};
+ std::queue<IR::Attribute> unused_input_generics{};
for (size_t index = 0; index < IR::NUM_GENERICS; ++index) {
const AttributeType input_type{runtime_info.generic_input_types[index]};
if (!runtime_info.previous_stage_stores.Generic(index) || !loads.Generic(index) ||
input_type == AttributeType::Disabled) {
- ununsed_input_generics.push(IR::Attribute::Generic0X + index * 4);
+ unused_input_generics.push(IR::Attribute::Generic0X + index * 4);
}
}
- auto mappings = GenerateLegacyToGenericMappings(loads, ununsed_input_generics);
+ auto mappings = GenerateLegacyToGenericMappings(
+ loads, unused_input_generics, runtime_info.previous_stage_legacy_stores_mapping);
for (IR::Block* const block : program.post_order_blocks) {
for (IR::Inst& inst : block->Instructions()) {
switch (inst.GetOpcode()) {
diff --git a/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp b/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp
index 9a7d47344..1bd8afd6f 100644
--- a/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp
+++ b/src/shader_recompiler/ir_opt/dead_code_elimination_pass.cpp
@@ -1,104 +1,24 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
-#include <algorithm>
-
-#include <boost/container/small_vector.hpp>
-
#include "shader_recompiler/frontend/ir/basic_block.h"
#include "shader_recompiler/frontend/ir/value.h"
#include "shader_recompiler/ir_opt/passes.h"
namespace Shader::Optimization {
-namespace {
-template <bool TEST_USES>
-void DeadInstElimination(IR::Block* const block) {
+
+void DeadCodeEliminationPass(IR::Program& program) {
// We iterate over the instructions in reverse order.
// This is because removing an instruction reduces the number of uses for earlier instructions.
- auto it{block->end()};
- while (it != block->begin()) {
- --it;
- if constexpr (TEST_USES) {
- if (it->HasUses() || it->MayHaveSideEffects()) {
- continue;
- }
- }
- it->Invalidate();
- it = block->Instructions().erase(it);
- }
-}
-
-void DeletedPhiArgElimination(IR::Program& program, std::span<const IR::Block*> dead_blocks) {
- for (IR::Block* const block : program.blocks) {
- for (IR::Inst& phi : *block) {
- if (!IR::IsPhi(phi)) {
- continue;
- }
- for (size_t i = 0; i < phi.NumArgs(); ++i) {
- if (std::ranges::find(dead_blocks, phi.PhiBlock(i)) == dead_blocks.end()) {
- continue;
- }
- // Phi operand at this index is an unreachable block
- phi.ErasePhiOperand(i);
- --i;
- }
- }
- }
-}
-
-void DeadBranchElimination(IR::Program& program) {
- boost::container::small_vector<const IR::Block*, 3> dead_blocks;
- const auto begin_it{program.syntax_list.begin()};
- for (auto node_it = begin_it; node_it != program.syntax_list.end(); ++node_it) {
- if (node_it->type != IR::AbstractSyntaxNode::Type::If) {
- continue;
- }
- IR::Inst* const cond_ref{node_it->data.if_node.cond.Inst()};
- const IR::U1 cond{cond_ref->Arg(0)};
- if (!cond.IsImmediate()) {
- continue;
- }
- if (cond.U1()) {
- continue;
- }
- // False immediate condition. Remove condition ref, erase the entire branch.
- cond_ref->Invalidate();
- // Account for nested if-statements within the if(false) branch
- u32 nested_ifs{1u};
- while (node_it->type != IR::AbstractSyntaxNode::Type::EndIf || nested_ifs > 0) {
- node_it = program.syntax_list.erase(node_it);
- switch (node_it->type) {
- case IR::AbstractSyntaxNode::Type::If:
- ++nested_ifs;
- break;
- case IR::AbstractSyntaxNode::Type::EndIf:
- --nested_ifs;
- break;
- case IR::AbstractSyntaxNode::Type::Block: {
- IR::Block* const block{node_it->data.block};
- DeadInstElimination<false>(block);
- dead_blocks.push_back(block);
- break;
- }
- default:
- break;
+ for (IR::Block* const block : program.post_order_blocks) {
+ auto it{block->end()};
+ while (it != block->begin()) {
+ --it;
+ if (!it->HasUses() && !it->MayHaveSideEffects()) {
+ it->Invalidate();
+ it = block->Instructions().erase(it);
}
}
- // Erase EndIf node of the if(false) branch
- node_it = program.syntax_list.erase(node_it);
- // Account for loop increment
- --node_it;
- }
- if (!dead_blocks.empty()) {
- DeletedPhiArgElimination(program, std::span(dead_blocks.data(), dead_blocks.size()));
- }
-}
-} // namespace
-
-void DeadCodeEliminationPass(IR::Program& program) {
- DeadBranchElimination(program);
- for (IR::Block* const block : program.post_order_blocks) {
- DeadInstElimination<true>(block);
}
}
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp
index 597112ba4..e8be58357 100644
--- a/src/shader_recompiler/ir_opt/texture_pass.cpp
+++ b/src/shader_recompiler/ir_opt/texture_pass.cpp
@@ -19,8 +19,10 @@ namespace {
struct ConstBufferAddr {
u32 index;
u32 offset;
+ u32 shift_left;
u32 secondary_index;
u32 secondary_offset;
+ u32 secondary_shift_left;
IR::U32 dynamic_offset;
u32 count;
bool has_secondary;
@@ -172,19 +174,41 @@ bool IsTextureInstruction(const IR::Inst& inst) {
return IndexedInstruction(inst) != IR::Opcode::Void;
}
-std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst);
+std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst, Environment& env);
-std::optional<ConstBufferAddr> Track(const IR::Value& value) {
- return IR::BreadthFirstSearch(value, TryGetConstBuffer);
+std::optional<ConstBufferAddr> Track(const IR::Value& value, Environment& env) {
+ return IR::BreadthFirstSearch(
+ value, [&env](const IR::Inst* inst) { return TryGetConstBuffer(inst, env); });
}
-std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) {
+std::optional<u32> TryGetConstant(IR::Value& value, Environment& env) {
+ const IR::Inst* inst = value.InstRecursive();
+ if (inst->GetOpcode() != IR::Opcode::GetCbufU32) {
+ return std::nullopt;
+ }
+ const IR::Value index{inst->Arg(0)};
+ const IR::Value offset{inst->Arg(1)};
+ if (!index.IsImmediate()) {
+ return std::nullopt;
+ }
+ if (!offset.IsImmediate()) {
+ return std::nullopt;
+ }
+ const auto index_number = index.U32();
+ if (index_number != 1) {
+ return std::nullopt;
+ }
+ const auto offset_number = offset.U32();
+ return env.ReadCbufValue(index_number, offset_number);
+}
+
+std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst, Environment& env) {
switch (inst->GetOpcode()) {
default:
return std::nullopt;
case IR::Opcode::BitwiseOr32: {
- std::optional lhs{Track(inst->Arg(0))};
- std::optional rhs{Track(inst->Arg(1))};
+ std::optional lhs{Track(inst->Arg(0), env)};
+ std::optional rhs{Track(inst->Arg(1), env)};
if (!lhs || !rhs) {
return std::nullopt;
}
@@ -194,19 +218,62 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) {
if (lhs->count > 1 || rhs->count > 1) {
return std::nullopt;
}
- if (lhs->index > rhs->index || lhs->offset > rhs->offset) {
+ if (lhs->shift_left > 0 || lhs->index > rhs->index || lhs->offset > rhs->offset) {
std::swap(lhs, rhs);
}
return ConstBufferAddr{
.index = lhs->index,
.offset = lhs->offset,
+ .shift_left = lhs->shift_left,
.secondary_index = rhs->index,
.secondary_offset = rhs->offset,
+ .secondary_shift_left = rhs->shift_left,
.dynamic_offset = {},
.count = 1,
.has_secondary = true,
};
}
+ case IR::Opcode::ShiftLeftLogical32: {
+ const IR::Value shift{inst->Arg(1)};
+ if (!shift.IsImmediate()) {
+ return std::nullopt;
+ }
+ std::optional lhs{Track(inst->Arg(0), env)};
+ if (lhs) {
+ lhs->shift_left = shift.U32();
+ }
+ return lhs;
+ break;
+ }
+ case IR::Opcode::BitwiseAnd32: {
+ IR::Value op1{inst->Arg(0)};
+ IR::Value op2{inst->Arg(1)};
+ if (op1.IsImmediate()) {
+ std::swap(op1, op2);
+ }
+ if (!op2.IsImmediate() && !op1.IsImmediate()) {
+ do {
+ auto try_index = TryGetConstant(op1, env);
+ if (try_index) {
+ op1 = op2;
+ op2 = IR::Value{*try_index};
+ break;
+ }
+ auto try_index_2 = TryGetConstant(op2, env);
+ if (try_index_2) {
+ op2 = IR::Value{*try_index_2};
+ break;
+ }
+ return std::nullopt;
+ } while (false);
+ }
+ std::optional lhs{Track(op1, env)};
+ if (lhs) {
+ lhs->shift_left = static_cast<u32>(std::countr_zero(op2.U32()));
+ }
+ return lhs;
+ break;
+ }
case IR::Opcode::GetCbufU32x2:
case IR::Opcode::GetCbufU32:
break;
@@ -222,8 +289,10 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) {
return ConstBufferAddr{
.index = index.U32(),
.offset = offset.U32(),
+ .shift_left = 0,
.secondary_index = 0,
.secondary_offset = 0,
+ .secondary_shift_left = 0,
.dynamic_offset = {},
.count = 1,
.has_secondary = false,
@@ -247,8 +316,10 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) {
return ConstBufferAddr{
.index = index.U32(),
.offset = base_offset,
+ .shift_left = 0,
.secondary_index = 0,
.secondary_offset = 0,
+ .secondary_shift_left = 0,
.dynamic_offset = dynamic_offset,
.count = 8,
.has_secondary = false,
@@ -258,7 +329,7 @@ std::optional<ConstBufferAddr> TryGetConstBuffer(const IR::Inst* inst) {
TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) {
ConstBufferAddr addr;
if (IsBindless(inst)) {
- const std::optional<ConstBufferAddr> track_addr{Track(inst.Arg(0))};
+ const std::optional<ConstBufferAddr> track_addr{Track(inst.Arg(0), env)};
if (!track_addr) {
throw NotImplementedException("Failed to track bindless texture constant buffer");
}
@@ -267,8 +338,10 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) {
addr = ConstBufferAddr{
.index = env.TextureBoundBuffer(),
.offset = inst.Arg(0).U32(),
+ .shift_left = 0,
.secondary_index = 0,
.secondary_offset = 0,
+ .secondary_shift_left = 0,
.dynamic_offset = {},
.count = 1,
.has_secondary = false,
@@ -284,8 +357,9 @@ TextureInst MakeInst(Environment& env, IR::Block* block, IR::Inst& inst) {
TextureType ReadTextureType(Environment& env, const ConstBufferAddr& cbuf) {
const u32 secondary_index{cbuf.has_secondary ? cbuf.secondary_index : cbuf.index};
const u32 secondary_offset{cbuf.has_secondary ? cbuf.secondary_offset : cbuf.offset};
- const u32 lhs_raw{env.ReadCbufValue(cbuf.index, cbuf.offset)};
- const u32 rhs_raw{env.ReadCbufValue(secondary_index, secondary_offset)};
+ const u32 lhs_raw{env.ReadCbufValue(cbuf.index, cbuf.offset) << cbuf.shift_left};
+ const u32 rhs_raw{env.ReadCbufValue(secondary_index, secondary_offset)
+ << cbuf.secondary_shift_left};
return env.ReadTextureType(lhs_raw | rhs_raw);
}
@@ -487,8 +561,10 @@ void TexturePass(Environment& env, IR::Program& program) {
.has_secondary = cbuf.has_secondary,
.cbuf_index = cbuf.index,
.cbuf_offset = cbuf.offset,
+ .shift_left = cbuf.shift_left,
.secondary_cbuf_index = cbuf.secondary_index,
.secondary_cbuf_offset = cbuf.secondary_offset,
+ .secondary_shift_left = cbuf.secondary_shift_left,
.count = cbuf.count,
.size_shift = DESCRIPTOR_SIZE_SHIFT,
});
@@ -499,8 +575,10 @@ void TexturePass(Environment& env, IR::Program& program) {
.has_secondary = cbuf.has_secondary,
.cbuf_index = cbuf.index,
.cbuf_offset = cbuf.offset,
+ .shift_left = cbuf.shift_left,
.secondary_cbuf_index = cbuf.secondary_index,
.secondary_cbuf_offset = cbuf.secondary_offset,
+ .secondary_shift_left = cbuf.secondary_shift_left,
.count = cbuf.count,
.size_shift = DESCRIPTOR_SIZE_SHIFT,
});
diff --git a/src/shader_recompiler/runtime_info.h b/src/shader_recompiler/runtime_info.h
index dcb5ab158..549b81ef7 100644
--- a/src/shader_recompiler/runtime_info.h
+++ b/src/shader_recompiler/runtime_info.h
@@ -4,6 +4,7 @@
#pragma once
#include <array>
+#include <map>
#include <optional>
#include <vector>
@@ -60,6 +61,7 @@ struct TransformFeedbackVarying {
struct RuntimeInfo {
std::array<AttributeType, 32> generic_input_types{};
VaryingState previous_stage_stores;
+ std::map<IR::Attribute, IR::Attribute> previous_stage_legacy_stores_mapping;
bool convert_depth_mode{};
bool force_early_z{};
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h
index e4b5ba567..a479e105e 100644
--- a/src/shader_recompiler/shader_info.h
+++ b/src/shader_recompiler/shader_info.h
@@ -5,6 +5,7 @@
#include <array>
#include <bitset>
+#include <map>
#include "common/common_types.h"
#include "shader_recompiler/frontend/ir/type.h"
@@ -61,8 +62,10 @@ struct TextureBufferDescriptor {
bool has_secondary;
u32 cbuf_index;
u32 cbuf_offset;
+ u32 shift_left;
u32 secondary_cbuf_index;
u32 secondary_cbuf_offset;
+ u32 secondary_shift_left;
u32 count;
u32 size_shift;
};
@@ -85,8 +88,10 @@ struct TextureDescriptor {
bool has_secondary;
u32 cbuf_index;
u32 cbuf_offset;
+ u32 shift_left;
u32 secondary_cbuf_index;
u32 secondary_cbuf_offset;
+ u32 secondary_shift_left;
u32 count;
u32 size_shift;
};
@@ -123,6 +128,8 @@ struct Info {
VaryingState stores;
VaryingState passthrough;
+ std::map<IR::Attribute, IR::Attribute> legacy_stores_mapping;
+
bool loads_indexed_attributes{};
std::array<bool, 8> stores_frag_color{};
diff --git a/src/tests/core/core_timing.cpp b/src/tests/core/core_timing.cpp
index 7c432a63c..284b2ae66 100644
--- a/src/tests/core/core_timing.cpp
+++ b/src/tests/core/core_timing.cpp
@@ -40,9 +40,6 @@ struct ScopeInit final {
core_timing.SetMulticore(true);
core_timing.Initialize([]() {});
}
- ~ScopeInit() {
- core_timing.Shutdown();
- }
Core::Timing::CoreTiming core_timing;
};
diff --git a/src/tests/video_core/buffer_base.cpp b/src/tests/video_core/buffer_base.cpp
index 71121e42a..f7236afab 100644
--- a/src/tests/video_core/buffer_base.cpp
+++ b/src/tests/video_core/buffer_base.cpp
@@ -44,7 +44,7 @@ public:
[[nodiscard]] unsigned Count() const noexcept {
unsigned count = 0;
- for (const auto [index, value] : page_table) {
+ for (const auto& [index, value] : page_table) {
count += value;
}
return count;
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 5b3808351..106991969 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -4,7 +4,7 @@
add_subdirectory(host_shaders)
if(LIBVA_FOUND)
- set_source_files_properties(command_classes/codecs/codec.cpp
+ set_source_files_properties(host1x/codecs/codec.cpp
PROPERTIES COMPILE_DEFINITIONS LIBVA_FOUND=1)
list(APPEND FFmpeg_LIBRARIES ${LIBVA_LIBRARIES})
endif()
@@ -15,26 +15,14 @@ add_library(video_core STATIC
buffer_cache/buffer_cache.h
cdma_pusher.cpp
cdma_pusher.h
- command_classes/codecs/codec.cpp
- command_classes/codecs/codec.h
- command_classes/codecs/h264.cpp
- command_classes/codecs/h264.h
- command_classes/codecs/vp8.cpp
- command_classes/codecs/vp8.h
- command_classes/codecs/vp9.cpp
- command_classes/codecs/vp9.h
- command_classes/codecs/vp9_types.h
- command_classes/host1x.cpp
- command_classes/host1x.h
- command_classes/nvdec.cpp
- command_classes/nvdec.h
- command_classes/nvdec_common.h
- command_classes/sync_manager.cpp
- command_classes/sync_manager.h
- command_classes/vic.cpp
- command_classes/vic.h
compatible_formats.cpp
compatible_formats.h
+ control/channel_state.cpp
+ control/channel_state.h
+ control/channel_state_cache.cpp
+ control/channel_state_cache.h
+ control/scheduler.cpp
+ control/scheduler.h
delayed_destruction_ring.h
dirty_flags.cpp
dirty_flags.h
@@ -54,7 +42,31 @@ add_library(video_core STATIC
engines/maxwell_3d.h
engines/maxwell_dma.cpp
engines/maxwell_dma.h
+ engines/puller.cpp
+ engines/puller.h
framebuffer_config.h
+ host1x/codecs/codec.cpp
+ host1x/codecs/codec.h
+ host1x/codecs/h264.cpp
+ host1x/codecs/h264.h
+ host1x/codecs/vp8.cpp
+ host1x/codecs/vp8.h
+ host1x/codecs/vp9.cpp
+ host1x/codecs/vp9.h
+ host1x/codecs/vp9_types.h
+ host1x/control.cpp
+ host1x/control.h
+ host1x/host1x.cpp
+ host1x/host1x.h
+ host1x/nvdec.cpp
+ host1x/nvdec.h
+ host1x/nvdec_common.h
+ host1x/sync_manager.cpp
+ host1x/sync_manager.h
+ host1x/syncpoint_manager.cpp
+ host1x/syncpoint_manager.h
+ host1x/vic.cpp
+ host1x/vic.h
macro/macro.cpp
macro/macro.h
macro/macro_hle.cpp
@@ -70,6 +82,7 @@ add_library(video_core STATIC
gpu_thread.h
memory_manager.cpp
memory_manager.h
+ pte_kind.h
query_cache.h
rasterizer_accelerated.cpp
rasterizer_accelerated.h
@@ -195,6 +208,7 @@ add_library(video_core STATIC
texture_cache/render_targets.h
texture_cache/samples_helper.h
texture_cache/slot_vector.h
+ texture_cache/texture_cache.cpp
texture_cache/texture_cache.h
texture_cache/texture_cache_base.h
texture_cache/types.h
@@ -265,14 +279,8 @@ if (MSVC)
else()
target_compile_options(video_core PRIVATE
-Werror=conversion
- -Wno-error=sign-conversion
- -Werror=pessimizing-move
- -Werror=redundant-move
- -Werror=type-limits
- $<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess>
- $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter>
- $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable>
+ -Wno-sign-conversion
)
endif()
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index f015dae56..2ba33543c 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -5,7 +5,6 @@
#include <algorithm>
#include <array>
-#include <deque>
#include <memory>
#include <mutex>
#include <numeric>
@@ -23,6 +22,7 @@
#include "common/settings.h"
#include "core/memory.h"
#include "video_core/buffer_cache/buffer_base.h"
+#include "video_core/control/channel_state_cache.h"
#include "video_core/delayed_destruction_ring.h"
#include "video_core/dirty_flags.h"
#include "video_core/engines/kepler_compute.h"
@@ -56,7 +56,7 @@ using UniformBufferSizes = std::array<std::array<u32, NUM_GRAPHICS_UNIFORM_BUFFE
using ComputeUniformBufferSizes = std::array<u32, NUM_COMPUTE_UNIFORM_BUFFERS>;
template <typename P>
-class BufferCache {
+class BufferCache : public VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo> {
// Page size for caching purposes.
// This is unrelated to the CPU page size and it can be changed as it seems optimal.
@@ -116,10 +116,7 @@ public:
static constexpr u32 DEFAULT_SKIP_CACHE_SIZE = static_cast<u32>(4_KiB);
explicit BufferCache(VideoCore::RasterizerInterface& rasterizer_,
- Tegra::Engines::Maxwell3D& maxwell3d_,
- Tegra::Engines::KeplerCompute& kepler_compute_,
- Tegra::MemoryManager& gpu_memory_, Core::Memory::Memory& cpu_memory_,
- Runtime& runtime_);
+ Core::Memory::Memory& cpu_memory_, Runtime& runtime_);
void TickFrame();
@@ -129,7 +126,7 @@ public:
void DownloadMemory(VAddr cpu_addr, u64 size);
- bool InlineMemory(VAddr dest_address, size_t copy_size, std::span<u8> inlined_buffer);
+ bool InlineMemory(VAddr dest_address, size_t copy_size, std::span<const u8> inlined_buffer);
void BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr, u32 size);
@@ -353,7 +350,7 @@ private:
void NotifyBufferDeletion();
- [[nodiscard]] Binding StorageBufferBinding(GPUVAddr ssbo_addr) const;
+ [[nodiscard]] Binding StorageBufferBinding(GPUVAddr ssbo_addr, bool is_written = false) const;
[[nodiscard]] TextureBufferBinding GetTextureBufferBinding(GPUVAddr gpu_addr, u32 size,
PixelFormat format);
@@ -367,9 +364,6 @@ private:
void ClearDownload(IntervalType subtract_interval);
VideoCore::RasterizerInterface& rasterizer;
- Tegra::Engines::Maxwell3D& maxwell3d;
- Tegra::Engines::KeplerCompute& kepler_compute;
- Tegra::MemoryManager& gpu_memory;
Core::Memory::Memory& cpu_memory;
SlotVector<Buffer> slot_buffers;
@@ -444,12 +438,8 @@ private:
template <class P>
BufferCache<P>::BufferCache(VideoCore::RasterizerInterface& rasterizer_,
- Tegra::Engines::Maxwell3D& maxwell3d_,
- Tegra::Engines::KeplerCompute& kepler_compute_,
- Tegra::MemoryManager& gpu_memory_, Core::Memory::Memory& cpu_memory_,
- Runtime& runtime_)
- : runtime{runtime_}, rasterizer{rasterizer_}, maxwell3d{maxwell3d_},
- kepler_compute{kepler_compute_}, gpu_memory{gpu_memory_}, cpu_memory{cpu_memory_} {
+ Core::Memory::Memory& cpu_memory_, Runtime& runtime_)
+ : runtime{runtime_}, rasterizer{rasterizer_}, cpu_memory{cpu_memory_} {
// Ensure the first slot is used for the null buffer
void(slot_buffers.insert(runtime, NullBufferParams{}));
common_ranges.clear();
@@ -552,8 +542,8 @@ void BufferCache<P>::ClearDownload(IntervalType subtract_interval) {
template <class P>
bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) {
- const std::optional<VAddr> cpu_src_address = gpu_memory.GpuToCpuAddress(src_address);
- const std::optional<VAddr> cpu_dest_address = gpu_memory.GpuToCpuAddress(dest_address);
+ const std::optional<VAddr> cpu_src_address = gpu_memory->GpuToCpuAddress(src_address);
+ const std::optional<VAddr> cpu_dest_address = gpu_memory->GpuToCpuAddress(dest_address);
if (!cpu_src_address || !cpu_dest_address) {
return false;
}
@@ -611,7 +601,7 @@ bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am
template <class P>
bool BufferCache<P>::DMAClear(GPUVAddr dst_address, u64 amount, u32 value) {
- const std::optional<VAddr> cpu_dst_address = gpu_memory.GpuToCpuAddress(dst_address);
+ const std::optional<VAddr> cpu_dst_address = gpu_memory->GpuToCpuAddress(dst_address);
if (!cpu_dst_address) {
return false;
}
@@ -635,7 +625,7 @@ bool BufferCache<P>::DMAClear(GPUVAddr dst_address, u64 amount, u32 value) {
template <class P>
void BufferCache<P>::BindGraphicsUniformBuffer(size_t stage, u32 index, GPUVAddr gpu_addr,
u32 size) {
- const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
+ const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
const Binding binding{
.cpu_addr = *cpu_addr,
.size = size,
@@ -673,7 +663,7 @@ void BufferCache<P>::BindHostGeometryBuffers(bool is_indexed) {
if (is_indexed) {
BindHostIndexBuffer();
} else if constexpr (!HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) {
- const auto& regs = maxwell3d.regs;
+ const auto& regs = maxwell3d->regs;
if (regs.draw.topology == Maxwell::PrimitiveTopology::Quads) {
runtime.BindQuadArrayIndexBuffer(regs.vertex_buffer.first, regs.vertex_buffer.count);
}
@@ -733,9 +723,9 @@ void BufferCache<P>::BindGraphicsStorageBuffer(size_t stage, size_t ssbo_index,
enabled_storage_buffers[stage] |= 1U << ssbo_index;
written_storage_buffers[stage] |= (is_written ? 1U : 0U) << ssbo_index;
- const auto& cbufs = maxwell3d.state.shader_stages[stage];
+ const auto& cbufs = maxwell3d->state.shader_stages[stage];
const GPUVAddr ssbo_addr = cbufs.const_buffers[cbuf_index].address + cbuf_offset;
- storage_buffers[stage][ssbo_index] = StorageBufferBinding(ssbo_addr);
+ storage_buffers[stage][ssbo_index] = StorageBufferBinding(ssbo_addr, is_written);
}
template <class P>
@@ -770,12 +760,12 @@ void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index,
enabled_compute_storage_buffers |= 1U << ssbo_index;
written_compute_storage_buffers |= (is_written ? 1U : 0U) << ssbo_index;
- const auto& launch_desc = kepler_compute.launch_description;
+ const auto& launch_desc = kepler_compute->launch_description;
ASSERT(((launch_desc.const_buffer_enable_mask >> cbuf_index) & 1) != 0);
const auto& cbufs = launch_desc.const_buffer_config;
const GPUVAddr ssbo_addr = cbufs[cbuf_index].Address() + cbuf_offset;
- compute_storage_buffers[ssbo_index] = StorageBufferBinding(ssbo_addr);
+ compute_storage_buffers[ssbo_index] = StorageBufferBinding(ssbo_addr, is_written);
}
template <class P>
@@ -836,6 +826,19 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
const bool is_accuracy_normal =
Settings::values.gpu_accuracy.GetValue() == Settings::GPUAccuracy::Normal;
+ auto it = committed_ranges.begin();
+ while (it != committed_ranges.end()) {
+ auto& current_intervals = *it;
+ auto next_it = std::next(it);
+ while (next_it != committed_ranges.end()) {
+ for (auto& interval : *next_it) {
+ current_intervals.subtract(interval);
+ }
+ next_it++;
+ }
+ it++;
+ }
+
boost::container::small_vector<std::pair<BufferCopy, BufferId>, 1> downloads;
u64 total_size_bytes = 0;
u64 largest_copy = 0;
@@ -991,19 +994,19 @@ void BufferCache<P>::BindHostIndexBuffer() {
const u32 size = index_buffer.size;
SynchronizeBuffer(buffer, index_buffer.cpu_addr, size);
if constexpr (HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT) {
- const u32 new_offset = offset + maxwell3d.regs.index_array.first *
- maxwell3d.regs.index_array.FormatSizeInBytes();
+ const u32 new_offset = offset + maxwell3d->regs.index_buffer.first *
+ maxwell3d->regs.index_buffer.FormatSizeInBytes();
runtime.BindIndexBuffer(buffer, new_offset, size);
} else {
- runtime.BindIndexBuffer(maxwell3d.regs.draw.topology, maxwell3d.regs.index_array.format,
- maxwell3d.regs.index_array.first, maxwell3d.regs.index_array.count,
- buffer, offset, size);
+ runtime.BindIndexBuffer(maxwell3d->regs.draw.topology, maxwell3d->regs.index_buffer.format,
+ maxwell3d->regs.index_buffer.first,
+ maxwell3d->regs.index_buffer.count, buffer, offset, size);
}
}
template <class P>
void BufferCache<P>::BindHostVertexBuffers() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
for (u32 index = 0; index < NUM_VERTEX_BUFFERS; ++index) {
const Binding& binding = vertex_buffers[index];
Buffer& buffer = slot_buffers[binding.buffer_id];
@@ -1014,7 +1017,7 @@ void BufferCache<P>::BindHostVertexBuffers() {
}
flags[Dirty::VertexBuffer0 + index] = false;
- const u32 stride = maxwell3d.regs.vertex_array[index].stride;
+ const u32 stride = maxwell3d->regs.vertex_streams[index].stride;
const u32 offset = buffer.Offset(binding.cpu_addr);
runtime.BindVertexBuffer(index, buffer, offset, binding.size, stride);
}
@@ -1154,7 +1157,7 @@ void BufferCache<P>::BindHostGraphicsTextureBuffers(size_t stage) {
template <class P>
void BufferCache<P>::BindHostTransformFeedbackBuffers() {
- if (maxwell3d.regs.tfb_enabled == 0) {
+ if (maxwell3d->regs.transform_feedback_enabled == 0) {
return;
}
for (u32 index = 0; index < NUM_TRANSFORM_FEEDBACK_BUFFERS; ++index) {
@@ -1239,16 +1242,19 @@ void BufferCache<P>::BindHostComputeTextureBuffers() {
template <class P>
void BufferCache<P>::DoUpdateGraphicsBuffers(bool is_indexed) {
- if (is_indexed) {
- UpdateIndexBuffer();
- }
- UpdateVertexBuffers();
- UpdateTransformFeedbackBuffers();
- for (size_t stage = 0; stage < NUM_STAGES; ++stage) {
- UpdateUniformBuffers(stage);
- UpdateStorageBuffers(stage);
- UpdateTextureBuffers(stage);
- }
+ do {
+ has_deleted_buffers = false;
+ if (is_indexed) {
+ UpdateIndexBuffer();
+ }
+ UpdateVertexBuffers();
+ UpdateTransformFeedbackBuffers();
+ for (size_t stage = 0; stage < NUM_STAGES; ++stage) {
+ UpdateUniformBuffers(stage);
+ UpdateStorageBuffers(stage);
+ UpdateTextureBuffers(stage);
+ }
+ } while (has_deleted_buffers);
}
template <class P>
@@ -1262,8 +1268,8 @@ template <class P>
void BufferCache<P>::UpdateIndexBuffer() {
// We have to check for the dirty flags and index count
// The index count is currently changed without updating the dirty flags
- const auto& index_array = maxwell3d.regs.index_array;
- auto& flags = maxwell3d.dirty.flags;
+ const auto& index_array = maxwell3d->regs.index_buffer;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::IndexBuffer] && last_index_count == index_array.count) {
return;
}
@@ -1272,7 +1278,7 @@ void BufferCache<P>::UpdateIndexBuffer() {
const GPUVAddr gpu_addr_begin = index_array.StartAddress();
const GPUVAddr gpu_addr_end = index_array.EndAddress();
- const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr_begin);
+ const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr_begin);
const u32 address_size = static_cast<u32>(gpu_addr_end - gpu_addr_begin);
const u32 draw_size = (index_array.count + index_array.first) * index_array.FormatSizeInBytes();
const u32 size = std::min(address_size, draw_size);
@@ -1289,8 +1295,8 @@ void BufferCache<P>::UpdateIndexBuffer() {
template <class P>
void BufferCache<P>::UpdateVertexBuffers() {
- auto& flags = maxwell3d.dirty.flags;
- if (!maxwell3d.dirty.flags[Dirty::VertexBuffers]) {
+ auto& flags = maxwell3d->dirty.flags;
+ if (!maxwell3d->dirty.flags[Dirty::VertexBuffers]) {
return;
}
flags[Dirty::VertexBuffers] = false;
@@ -1302,33 +1308,25 @@ void BufferCache<P>::UpdateVertexBuffers() {
template <class P>
void BufferCache<P>::UpdateVertexBuffer(u32 index) {
- if (!maxwell3d.dirty.flags[Dirty::VertexBuffer0 + index]) {
+ if (!maxwell3d->dirty.flags[Dirty::VertexBuffer0 + index]) {
return;
}
- const auto& array = maxwell3d.regs.vertex_array[index];
- const auto& limit = maxwell3d.regs.vertex_array_limit[index];
- const GPUVAddr gpu_addr_begin = array.StartAddress();
- const GPUVAddr gpu_addr_end = limit.LimitAddress() + 1;
- const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr_begin);
- u32 address_size = static_cast<u32>(gpu_addr_end - gpu_addr_begin);
- if (address_size >= 64_MiB) {
- // Reported vertex buffer size is very large, cap to mapped buffer size
- GPUVAddr submapped_addr_end = gpu_addr_begin;
-
- const auto ranges{gpu_memory.GetSubmappedRange(gpu_addr_begin, address_size)};
- if (ranges.size() > 0) {
- const auto& [addr, size] = *ranges.begin();
- submapped_addr_end = addr + size;
- }
-
- address_size =
- std::min(address_size, static_cast<u32>(submapped_addr_end - gpu_addr_begin));
- }
- const u32 size = address_size; // TODO: Analyze stride and number of vertices
- if (array.enable == 0 || size == 0 || !cpu_addr) {
+ const auto& array = maxwell3d->regs.vertex_streams[index];
+ const auto& limit = maxwell3d->regs.vertex_stream_limits[index];
+ const GPUVAddr gpu_addr_begin = array.Address();
+ const GPUVAddr gpu_addr_end = limit.Address() + 1;
+ const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr_begin);
+ u32 address_size = static_cast<u32>(
+ std::min(gpu_addr_end - gpu_addr_begin, static_cast<u64>(std::numeric_limits<u32>::max())));
+ if (array.enable == 0 || address_size == 0 || !cpu_addr) {
vertex_buffers[index] = NULL_BINDING;
return;
}
+ if (!gpu_memory->IsWithinGPUAddressRange(gpu_addr_end)) {
+ address_size =
+ static_cast<u32>(gpu_memory->MaxContinousRange(gpu_addr_begin, address_size));
+ }
+ const u32 size = address_size; // TODO: Analyze stride and number of vertices
vertex_buffers[index] = Binding{
.cpu_addr = *cpu_addr,
.size = size,
@@ -1382,7 +1380,7 @@ void BufferCache<P>::UpdateTextureBuffers(size_t stage) {
template <class P>
void BufferCache<P>::UpdateTransformFeedbackBuffers() {
- if (maxwell3d.regs.tfb_enabled == 0) {
+ if (maxwell3d->regs.transform_feedback_enabled == 0) {
return;
}
for (u32 index = 0; index < NUM_TRANSFORM_FEEDBACK_BUFFERS; ++index) {
@@ -1392,11 +1390,11 @@ void BufferCache<P>::UpdateTransformFeedbackBuffers() {
template <class P>
void BufferCache<P>::UpdateTransformFeedbackBuffer(u32 index) {
- const auto& binding = maxwell3d.regs.tfb_bindings[index];
- const GPUVAddr gpu_addr = binding.Address() + binding.buffer_offset;
- const u32 size = binding.buffer_size;
- const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
- if (binding.buffer_enable == 0 || size == 0 || !cpu_addr) {
+ const auto& binding = maxwell3d->regs.transform_feedback.buffers[index];
+ const GPUVAddr gpu_addr = binding.Address() + binding.start_offset;
+ const u32 size = binding.size;
+ const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
+ if (binding.enable == 0 || size == 0 || !cpu_addr) {
transform_feedback_buffers[index] = NULL_BINDING;
return;
}
@@ -1414,10 +1412,10 @@ void BufferCache<P>::UpdateComputeUniformBuffers() {
ForEachEnabledBit(enabled_compute_uniform_buffer_mask, [&](u32 index) {
Binding& binding = compute_uniform_buffers[index];
binding = NULL_BINDING;
- const auto& launch_desc = kepler_compute.launch_description;
+ const auto& launch_desc = kepler_compute->launch_description;
if (((launch_desc.const_buffer_enable_mask >> index) & 1) != 0) {
const auto& cbuf = launch_desc.const_buffer_config[index];
- const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(cbuf.Address());
+ const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(cbuf.Address());
if (cpu_addr) {
binding.cpu_addr = *cpu_addr;
binding.size = cbuf.size;
@@ -1567,6 +1565,8 @@ BufferId BufferCache<P>::CreateBuffer(VAddr cpu_addr, u32 wanted_size) {
const OverlapResult overlap = ResolveOverlaps(cpu_addr, wanted_size);
const u32 size = static_cast<u32>(overlap.end - overlap.begin);
const BufferId new_buffer_id = slot_buffers.insert(runtime, rasterizer, overlap.begin, size);
+ auto& new_buffer = slot_buffers[new_buffer_id];
+ runtime.ClearBuffer(new_buffer, 0, new_buffer.SizeBytes(), 0);
for (const BufferId overlap_id : overlap.ids) {
JoinOverlap(new_buffer_id, overlap_id, !overlap.has_stream_leap);
}
@@ -1695,7 +1695,7 @@ void BufferCache<P>::MappedUploadMemory(Buffer& buffer, u64 total_size_bytes,
template <class P>
bool BufferCache<P>::InlineMemory(VAddr dest_address, size_t copy_size,
- std::span<u8> inlined_buffer) {
+ std::span<const u8> inlined_buffer) {
const bool is_dirty = IsRegionRegistered(dest_address, copy_size);
if (!is_dirty) {
return false;
@@ -1831,7 +1831,7 @@ void BufferCache<P>::NotifyBufferDeletion() {
dirty_uniform_buffers.fill(~u32{0});
uniform_buffer_binding_sizes.fill({});
}
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
flags[Dirty::IndexBuffer] = true;
flags[Dirty::VertexBuffers] = true;
for (u32 index = 0; index < NUM_VERTEX_BUFFERS; ++index) {
@@ -1841,16 +1841,18 @@ void BufferCache<P>::NotifyBufferDeletion() {
}
template <class P>
-typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr ssbo_addr) const {
- const GPUVAddr gpu_addr = gpu_memory.Read<u64>(ssbo_addr);
- const u32 size = gpu_memory.Read<u32>(ssbo_addr + 8);
- const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
+typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr ssbo_addr,
+ bool is_written) const {
+ const GPUVAddr gpu_addr = gpu_memory->Read<u64>(ssbo_addr);
+ const u32 size = gpu_memory->Read<u32>(ssbo_addr + 8);
+ const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
if (!cpu_addr || size == 0) {
return NULL_BINDING;
}
+ const VAddr cpu_end = Common::AlignUp(*cpu_addr + size, Core::Memory::YUZU_PAGESIZE);
const Binding binding{
.cpu_addr = *cpu_addr,
- .size = size,
+ .size = is_written ? size : static_cast<u32>(cpu_end - *cpu_addr),
.buffer_id = BufferId{},
};
return binding;
@@ -1859,7 +1861,7 @@ typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr s
template <class P>
typename BufferCache<P>::TextureBufferBinding BufferCache<P>::GetTextureBufferBinding(
GPUVAddr gpu_addr, u32 size, PixelFormat format) {
- const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
+ const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
TextureBufferBinding binding;
if (!cpu_addr || size == 0) {
binding.cpu_addr = 0;
diff --git a/src/video_core/cdma_pusher.cpp b/src/video_core/cdma_pusher.cpp
index 8e890a85e..28a2d2090 100644
--- a/src/video_core/cdma_pusher.cpp
+++ b/src/video_core/cdma_pusher.cpp
@@ -2,20 +2,22 @@
// SPDX-License-Identifier: MIT
#include <bit>
-#include "command_classes/host1x.h"
-#include "command_classes/nvdec.h"
-#include "command_classes/vic.h"
#include "video_core/cdma_pusher.h"
-#include "video_core/command_classes/sync_manager.h"
#include "video_core/engines/maxwell_3d.h"
-#include "video_core/gpu.h"
+#include "video_core/host1x/control.h"
+#include "video_core/host1x/host1x.h"
+#include "video_core/host1x/nvdec.h"
+#include "video_core/host1x/nvdec_common.h"
+#include "video_core/host1x/sync_manager.h"
+#include "video_core/host1x/vic.h"
+#include "video_core/memory_manager.h"
namespace Tegra {
-CDmaPusher::CDmaPusher(GPU& gpu_)
- : gpu{gpu_}, nvdec_processor(std::make_shared<Nvdec>(gpu)),
- vic_processor(std::make_unique<Vic>(gpu, nvdec_processor)),
- host1x_processor(std::make_unique<Host1x>(gpu)),
- sync_manager(std::make_unique<SyncptIncrManager>(gpu)) {}
+CDmaPusher::CDmaPusher(Host1x::Host1x& host1x_)
+ : host1x{host1x_}, nvdec_processor(std::make_shared<Host1x::Nvdec>(host1x)),
+ vic_processor(std::make_unique<Host1x::Vic>(host1x, nvdec_processor)),
+ host1x_processor(std::make_unique<Host1x::Control>(host1x)),
+ sync_manager(std::make_unique<Host1x::SyncptIncrManager>(host1x)) {}
CDmaPusher::~CDmaPusher() = default;
@@ -109,16 +111,17 @@ void CDmaPusher::ExecuteCommand(u32 state_offset, u32 data) {
case ThiMethod::SetMethod1:
LOG_DEBUG(Service_NVDRV, "VIC method 0x{:X}, Args=({})",
static_cast<u32>(vic_thi_state.method_0), data);
- vic_processor->ProcessMethod(static_cast<Vic::Method>(vic_thi_state.method_0), data);
+ vic_processor->ProcessMethod(static_cast<Host1x::Vic::Method>(vic_thi_state.method_0),
+ data);
break;
default:
break;
}
break;
- case ChClassId::Host1x:
+ case ChClassId::Control:
// This device is mainly for syncpoint synchronization
LOG_DEBUG(Service_NVDRV, "Host1X Class Method");
- host1x_processor->ProcessMethod(static_cast<Host1x::Method>(offset), data);
+ host1x_processor->ProcessMethod(static_cast<Host1x::Control::Method>(offset), data);
break;
default:
UNIMPLEMENTED_MSG("Current class not implemented {:X}", static_cast<u32>(current_class));
diff --git a/src/video_core/cdma_pusher.h b/src/video_core/cdma_pusher.h
index d6ffef95f..83112dfce 100644
--- a/src/video_core/cdma_pusher.h
+++ b/src/video_core/cdma_pusher.h
@@ -12,11 +12,13 @@
namespace Tegra {
-class GPU;
+namespace Host1x {
+class Control;
class Host1x;
class Nvdec;
class SyncptIncrManager;
class Vic;
+} // namespace Host1x
enum class ChSubmissionMode : u32 {
SetClass = 0,
@@ -30,7 +32,7 @@ enum class ChSubmissionMode : u32 {
enum class ChClassId : u32 {
NoClass = 0x0,
- Host1x = 0x1,
+ Control = 0x1,
VideoEncodeMpeg = 0x20,
VideoEncodeNvEnc = 0x21,
VideoStreamingVi = 0x30,
@@ -88,7 +90,7 @@ enum class ThiMethod : u32 {
class CDmaPusher {
public:
- explicit CDmaPusher(GPU& gpu_);
+ explicit CDmaPusher(Host1x::Host1x& host1x);
~CDmaPusher();
/// Process the command entry
@@ -101,11 +103,11 @@ private:
/// Write arguments value to the ThiRegisters member at the specified offset
void ThiStateWrite(ThiRegisters& state, u32 offset, u32 argument);
- GPU& gpu;
- std::shared_ptr<Tegra::Nvdec> nvdec_processor;
- std::unique_ptr<Tegra::Vic> vic_processor;
- std::unique_ptr<Tegra::Host1x> host1x_processor;
- std::unique_ptr<SyncptIncrManager> sync_manager;
+ Host1x::Host1x& host1x;
+ std::shared_ptr<Tegra::Host1x::Nvdec> nvdec_processor;
+ std::unique_ptr<Tegra::Host1x::Vic> vic_processor;
+ std::unique_ptr<Tegra::Host1x::Control> host1x_processor;
+ std::unique_ptr<Host1x::SyncptIncrManager> sync_manager;
ChClassId current_class{};
ThiRegisters vic_thi_state{};
ThiRegisters nvdec_thi_state{};
diff --git a/src/video_core/command_classes/host1x.cpp b/src/video_core/command_classes/host1x.cpp
deleted file mode 100644
index 11855fe10..000000000
--- a/src/video_core/command_classes/host1x.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/assert.h"
-#include "video_core/command_classes/host1x.h"
-#include "video_core/gpu.h"
-
-Tegra::Host1x::Host1x(GPU& gpu_) : gpu(gpu_) {}
-
-Tegra::Host1x::~Host1x() = default;
-
-void Tegra::Host1x::ProcessMethod(Method method, u32 argument) {
- switch (method) {
- case Method::LoadSyncptPayload32:
- syncpoint_value = argument;
- break;
- case Method::WaitSyncpt:
- case Method::WaitSyncpt32:
- Execute(argument);
- break;
- default:
- UNIMPLEMENTED_MSG("Host1x method 0x{:X}", static_cast<u32>(method));
- break;
- }
-}
-
-void Tegra::Host1x::Execute(u32 data) {
- gpu.WaitFence(data, syncpoint_value);
-}
diff --git a/src/video_core/control/channel_state.cpp b/src/video_core/control/channel_state.cpp
new file mode 100644
index 000000000..cdecc3a91
--- /dev/null
+++ b/src/video_core/control/channel_state.cpp
@@ -0,0 +1,40 @@
+// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "common/assert.h"
+#include "video_core/control/channel_state.h"
+#include "video_core/dma_pusher.h"
+#include "video_core/engines/fermi_2d.h"
+#include "video_core/engines/kepler_compute.h"
+#include "video_core/engines/kepler_memory.h"
+#include "video_core/engines/maxwell_3d.h"
+#include "video_core/engines/maxwell_dma.h"
+#include "video_core/engines/puller.h"
+#include "video_core/memory_manager.h"
+
+namespace Tegra::Control {
+
+ChannelState::ChannelState(s32 bind_id_) : bind_id{bind_id_}, initialized{} {}
+
+void ChannelState::Init(Core::System& system, GPU& gpu) {
+ ASSERT(memory_manager);
+ dma_pusher = std::make_unique<Tegra::DmaPusher>(system, gpu, *memory_manager, *this);
+ maxwell_3d = std::make_unique<Engines::Maxwell3D>(system, *memory_manager);
+ fermi_2d = std::make_unique<Engines::Fermi2D>();
+ kepler_compute = std::make_unique<Engines::KeplerCompute>(system, *memory_manager);
+ maxwell_dma = std::make_unique<Engines::MaxwellDMA>(system, *memory_manager);
+ kepler_memory = std::make_unique<Engines::KeplerMemory>(system, *memory_manager);
+ initialized = true;
+}
+
+void ChannelState::BindRasterizer(VideoCore::RasterizerInterface* rasterizer) {
+ dma_pusher->BindRasterizer(rasterizer);
+ memory_manager->BindRasterizer(rasterizer);
+ maxwell_3d->BindRasterizer(rasterizer);
+ fermi_2d->BindRasterizer(rasterizer);
+ kepler_memory->BindRasterizer(rasterizer);
+ kepler_compute->BindRasterizer(rasterizer);
+ maxwell_dma->BindRasterizer(rasterizer);
+}
+
+} // namespace Tegra::Control
diff --git a/src/video_core/control/channel_state.h b/src/video_core/control/channel_state.h
new file mode 100644
index 000000000..3a7b9872c
--- /dev/null
+++ b/src/video_core/control/channel_state.h
@@ -0,0 +1,68 @@
+// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <memory>
+
+#include "common/common_types.h"
+
+namespace Core {
+class System;
+}
+
+namespace VideoCore {
+class RasterizerInterface;
+}
+
+namespace Tegra {
+
+class GPU;
+
+namespace Engines {
+class Puller;
+class Fermi2D;
+class Maxwell3D;
+class MaxwellDMA;
+class KeplerCompute;
+class KeplerMemory;
+} // namespace Engines
+
+class MemoryManager;
+class DmaPusher;
+
+namespace Control {
+
+struct ChannelState {
+ explicit ChannelState(s32 bind_id);
+ ChannelState(const ChannelState& state) = delete;
+ ChannelState& operator=(const ChannelState&) = delete;
+ ChannelState(ChannelState&& other) noexcept = default;
+ ChannelState& operator=(ChannelState&& other) noexcept = default;
+
+ void Init(Core::System& system, GPU& gpu);
+
+ void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
+
+ s32 bind_id = -1;
+ /// 3D engine
+ std::unique_ptr<Engines::Maxwell3D> maxwell_3d;
+ /// 2D engine
+ std::unique_ptr<Engines::Fermi2D> fermi_2d;
+ /// Compute engine
+ std::unique_ptr<Engines::KeplerCompute> kepler_compute;
+ /// DMA engine
+ std::unique_ptr<Engines::MaxwellDMA> maxwell_dma;
+ /// Inline memory engine
+ std::unique_ptr<Engines::KeplerMemory> kepler_memory;
+
+ std::shared_ptr<MemoryManager> memory_manager;
+
+ std::unique_ptr<DmaPusher> dma_pusher;
+
+ bool initialized{};
+};
+
+} // namespace Control
+
+} // namespace Tegra
diff --git a/src/video_core/control/channel_state_cache.cpp b/src/video_core/control/channel_state_cache.cpp
new file mode 100644
index 000000000..4ebeb6356
--- /dev/null
+++ b/src/video_core/control/channel_state_cache.cpp
@@ -0,0 +1,14 @@
+// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "video_core/control/channel_state_cache.inc"
+
+namespace VideoCommon {
+
+ChannelInfo::ChannelInfo(Tegra::Control::ChannelState& channel_state)
+ : maxwell3d{*channel_state.maxwell_3d}, kepler_compute{*channel_state.kepler_compute},
+ gpu_memory{*channel_state.memory_manager} {}
+
+template class VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo>;
+
+} // namespace VideoCommon
diff --git a/src/video_core/control/channel_state_cache.h b/src/video_core/control/channel_state_cache.h
new file mode 100644
index 000000000..584a0c26c
--- /dev/null
+++ b/src/video_core/control/channel_state_cache.h
@@ -0,0 +1,101 @@
+// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <deque>
+#include <limits>
+#include <mutex>
+#include <optional>
+#include <unordered_map>
+#include <vector>
+
+#include "common/common_types.h"
+
+namespace Tegra {
+
+namespace Engines {
+class Maxwell3D;
+class KeplerCompute;
+} // namespace Engines
+
+class MemoryManager;
+
+namespace Control {
+struct ChannelState;
+}
+
+} // namespace Tegra
+
+namespace VideoCommon {
+
+class ChannelInfo {
+public:
+ ChannelInfo() = delete;
+ explicit ChannelInfo(Tegra::Control::ChannelState& state);
+ ChannelInfo(const ChannelInfo& state) = delete;
+ ChannelInfo& operator=(const ChannelInfo&) = delete;
+ ChannelInfo(ChannelInfo&& other) = default;
+ ChannelInfo& operator=(ChannelInfo&& other) = default;
+
+ Tegra::Engines::Maxwell3D& maxwell3d;
+ Tegra::Engines::KeplerCompute& kepler_compute;
+ Tegra::MemoryManager& gpu_memory;
+};
+
+template <class P>
+class ChannelSetupCaches {
+public:
+ /// Operations for seting the channel of execution.
+ virtual ~ChannelSetupCaches();
+
+ /// Create channel state.
+ virtual void CreateChannel(Tegra::Control::ChannelState& channel);
+
+ /// Bind a channel for execution.
+ void BindToChannel(s32 id);
+
+ /// Erase channel's state.
+ void EraseChannel(s32 id);
+
+ Tegra::MemoryManager* GetFromID(size_t id) const {
+ std::unique_lock<std::mutex> lk(config_mutex);
+ const auto ref = address_spaces.find(id);
+ return ref->second.gpu_memory;
+ }
+
+ std::optional<size_t> getStorageID(size_t id) const {
+ std::unique_lock<std::mutex> lk(config_mutex);
+ const auto ref = address_spaces.find(id);
+ if (ref == address_spaces.end()) {
+ return std::nullopt;
+ }
+ return ref->second.storage_id;
+ }
+
+protected:
+ static constexpr size_t UNSET_CHANNEL{std::numeric_limits<size_t>::max()};
+
+ P* channel_state;
+ size_t current_channel_id{UNSET_CHANNEL};
+ size_t current_address_space{};
+ Tegra::Engines::Maxwell3D* maxwell3d;
+ Tegra::Engines::KeplerCompute* kepler_compute;
+ Tegra::MemoryManager* gpu_memory;
+
+ std::deque<P> channel_storage;
+ std::deque<size_t> free_channel_ids;
+ std::unordered_map<s32, size_t> channel_map;
+ std::vector<size_t> active_channel_ids;
+ struct AddresSpaceRef {
+ size_t ref_count;
+ size_t storage_id;
+ Tegra::MemoryManager* gpu_memory;
+ };
+ std::unordered_map<size_t, AddresSpaceRef> address_spaces;
+ mutable std::mutex config_mutex;
+
+ virtual void OnGPUASRegister([[maybe_unused]] size_t map_id) {}
+};
+
+} // namespace VideoCommon
diff --git a/src/video_core/control/channel_state_cache.inc b/src/video_core/control/channel_state_cache.inc
new file mode 100644
index 000000000..460313893
--- /dev/null
+++ b/src/video_core/control/channel_state_cache.inc
@@ -0,0 +1,86 @@
+// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include <algorithm>
+
+#include "video_core/control/channel_state.h"
+#include "video_core/control/channel_state_cache.h"
+#include "video_core/engines/kepler_compute.h"
+#include "video_core/engines/maxwell_3d.h"
+#include "video_core/memory_manager.h"
+
+namespace VideoCommon {
+
+template <class P>
+ChannelSetupCaches<P>::~ChannelSetupCaches() = default;
+
+template <class P>
+void ChannelSetupCaches<P>::CreateChannel(struct Tegra::Control::ChannelState& channel) {
+ std::unique_lock<std::mutex> lk(config_mutex);
+ ASSERT(channel_map.find(channel.bind_id) == channel_map.end() && channel.bind_id >= 0);
+ auto new_id = [this, &channel]() {
+ if (!free_channel_ids.empty()) {
+ auto id = free_channel_ids.front();
+ free_channel_ids.pop_front();
+ new (&channel_storage[id]) P(channel);
+ return id;
+ }
+ channel_storage.emplace_back(channel);
+ return channel_storage.size() - 1;
+ }();
+ channel_map.emplace(channel.bind_id, new_id);
+ if (current_channel_id != UNSET_CHANNEL) {
+ channel_state = &channel_storage[current_channel_id];
+ }
+ active_channel_ids.push_back(new_id);
+ auto as_it = address_spaces.find(channel.memory_manager->GetID());
+ if (as_it != address_spaces.end()) {
+ as_it->second.ref_count++;
+ return;
+ }
+ AddresSpaceRef new_gpu_mem_ref{
+ .ref_count = 1,
+ .storage_id = address_spaces.size(),
+ .gpu_memory = channel.memory_manager.get(),
+ };
+ address_spaces.emplace(channel.memory_manager->GetID(), new_gpu_mem_ref);
+ OnGPUASRegister(channel.memory_manager->GetID());
+}
+
+/// Bind a channel for execution.
+template <class P>
+void ChannelSetupCaches<P>::BindToChannel(s32 id) {
+ std::unique_lock<std::mutex> lk(config_mutex);
+ auto it = channel_map.find(id);
+ ASSERT(it != channel_map.end() && id >= 0);
+ current_channel_id = it->second;
+ channel_state = &channel_storage[current_channel_id];
+ maxwell3d = &channel_state->maxwell3d;
+ kepler_compute = &channel_state->kepler_compute;
+ gpu_memory = &channel_state->gpu_memory;
+ current_address_space = gpu_memory->GetID();
+}
+
+/// Erase channel's channel_state.
+template <class P>
+void ChannelSetupCaches<P>::EraseChannel(s32 id) {
+ std::unique_lock<std::mutex> lk(config_mutex);
+ const auto it = channel_map.find(id);
+ ASSERT(it != channel_map.end() && id >= 0);
+ const auto this_id = it->second;
+ free_channel_ids.push_back(this_id);
+ channel_map.erase(it);
+ if (this_id == current_channel_id) {
+ current_channel_id = UNSET_CHANNEL;
+ channel_state = nullptr;
+ maxwell3d = nullptr;
+ kepler_compute = nullptr;
+ gpu_memory = nullptr;
+ } else if (current_channel_id != UNSET_CHANNEL) {
+ channel_state = &channel_storage[current_channel_id];
+ }
+ active_channel_ids.erase(
+ std::find(active_channel_ids.begin(), active_channel_ids.end(), this_id));
+}
+
+} // namespace VideoCommon
diff --git a/src/video_core/control/scheduler.cpp b/src/video_core/control/scheduler.cpp
new file mode 100644
index 000000000..f7cbe204e
--- /dev/null
+++ b/src/video_core/control/scheduler.cpp
@@ -0,0 +1,32 @@
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include <memory>
+
+#include "common/assert.h"
+#include "video_core/control/channel_state.h"
+#include "video_core/control/scheduler.h"
+#include "video_core/gpu.h"
+
+namespace Tegra::Control {
+Scheduler::Scheduler(GPU& gpu_) : gpu{gpu_} {}
+
+Scheduler::~Scheduler() = default;
+
+void Scheduler::Push(s32 channel, CommandList&& entries) {
+ std::unique_lock lk(scheduling_guard);
+ auto it = channels.find(channel);
+ ASSERT(it != channels.end());
+ auto channel_state = it->second;
+ gpu.BindChannel(channel_state->bind_id);
+ channel_state->dma_pusher->Push(std::move(entries));
+ channel_state->dma_pusher->DispatchCalls();
+}
+
+void Scheduler::DeclareChannel(std::shared_ptr<ChannelState> new_channel) {
+ s32 channel = new_channel->bind_id;
+ std::unique_lock lk(scheduling_guard);
+ channels.emplace(channel, new_channel);
+}
+
+} // namespace Tegra::Control
diff --git a/src/video_core/control/scheduler.h b/src/video_core/control/scheduler.h
new file mode 100644
index 000000000..44addf61c
--- /dev/null
+++ b/src/video_core/control/scheduler.h
@@ -0,0 +1,37 @@
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <memory>
+#include <mutex>
+#include <unordered_map>
+
+#include "video_core/dma_pusher.h"
+
+namespace Tegra {
+
+class GPU;
+
+namespace Control {
+
+struct ChannelState;
+
+class Scheduler {
+public:
+ explicit Scheduler(GPU& gpu_);
+ ~Scheduler();
+
+ void Push(s32 channel, CommandList&& entries);
+
+ void DeclareChannel(std::shared_ptr<ChannelState> new_channel);
+
+private:
+ std::unordered_map<s32, std::shared_ptr<ChannelState>> channels;
+ std::mutex scheduling_guard;
+ GPU& gpu;
+};
+
+} // namespace Control
+
+} // namespace Tegra
diff --git a/src/video_core/dirty_flags.cpp b/src/video_core/dirty_flags.cpp
index 9dc4341f0..c2ecc12f5 100644
--- a/src/video_core/dirty_flags.cpp
+++ b/src/video_core/dirty_flags.cpp
@@ -17,21 +17,23 @@ using Tegra::Engines::Maxwell3D;
void SetupDirtyVertexBuffers(Maxwell3D::DirtyState::Tables& tables) {
static constexpr std::size_t num_array = 3;
for (std::size_t i = 0; i < Maxwell3D::Regs::NumVertexArrays; ++i) {
- const std::size_t array_offset = OFF(vertex_array) + i * NUM(vertex_array[0]);
- const std::size_t limit_offset = OFF(vertex_array_limit) + i * NUM(vertex_array_limit[0]);
+ const std::size_t array_offset = OFF(vertex_streams) + i * NUM(vertex_streams[0]);
+ const std::size_t limit_offset =
+ OFF(vertex_stream_limits) + i * NUM(vertex_stream_limits[0]);
FillBlock(tables, array_offset, num_array, VertexBuffer0 + i, VertexBuffers);
- FillBlock(tables, limit_offset, NUM(vertex_array_limit), VertexBuffer0 + i, VertexBuffers);
+ FillBlock(tables, limit_offset, NUM(vertex_stream_limits), VertexBuffer0 + i,
+ VertexBuffers);
}
}
void SetupIndexBuffer(Maxwell3D::DirtyState::Tables& tables) {
- FillBlock(tables[0], OFF(index_array), NUM(index_array), IndexBuffer);
+ FillBlock(tables[0], OFF(index_buffer), NUM(index_buffer), IndexBuffer);
}
void SetupDirtyDescriptors(Maxwell3D::DirtyState::Tables& tables) {
- FillBlock(tables[0], OFF(tic), NUM(tic), Descriptors);
- FillBlock(tables[0], OFF(tsc), NUM(tsc), Descriptors);
+ FillBlock(tables[0], OFF(tex_header), NUM(tex_header), Descriptors);
+ FillBlock(tables[0], OFF(tex_sampler), NUM(tex_sampler), Descriptors);
}
void SetupDirtyRenderTargets(Maxwell3D::DirtyState::Tables& tables) {
@@ -42,7 +44,7 @@ void SetupDirtyRenderTargets(Maxwell3D::DirtyState::Tables& tables) {
FillBlock(tables[0], begin + rt * num_per_rt, num_per_rt, ColorBuffer0 + rt);
}
FillBlock(tables[1], begin, num, RenderTargets);
- FillBlock(tables[0], OFF(render_area), NUM(render_area), RenderTargets);
+ FillBlock(tables[0], OFF(surface_clip), NUM(surface_clip), RenderTargets);
tables[0][OFF(rt_control)] = RenderTargets;
tables[1][OFF(rt_control)] = RenderTargetControl;
@@ -52,15 +54,15 @@ void SetupDirtyRenderTargets(Maxwell3D::DirtyState::Tables& tables) {
const u8 flag = zeta_flags[i];
auto& table = tables[i];
table[OFF(zeta_enable)] = flag;
- table[OFF(zeta_width)] = flag;
- table[OFF(zeta_height)] = flag;
+ table[OFF(zeta_size.width)] = flag;
+ table[OFF(zeta_size.height)] = flag;
FillBlock(table, OFF(zeta), NUM(zeta), flag);
}
}
void SetupDirtyShaders(Maxwell3D::DirtyState::Tables& tables) {
- FillBlock(tables[0], OFF(shader_config[0]),
- NUM(shader_config[0]) * Maxwell3D::Regs::MaxShaderProgram, Shaders);
+ FillBlock(tables[0], OFF(pipelines), NUM(pipelines[0]) * Maxwell3D::Regs::MaxShaderProgram,
+ Shaders);
}
} // Anonymous namespace
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp
index 29b8582ab..9835e3ac1 100644
--- a/src/video_core/dma_pusher.cpp
+++ b/src/video_core/dma_pusher.cpp
@@ -12,7 +12,10 @@
namespace Tegra {
-DmaPusher::DmaPusher(Core::System& system_, GPU& gpu_) : gpu{gpu_}, system{system_} {}
+DmaPusher::DmaPusher(Core::System& system_, GPU& gpu_, MemoryManager& memory_manager_,
+ Control::ChannelState& channel_state_)
+ : gpu{gpu_}, system{system_}, memory_manager{memory_manager_}, puller{gpu_, memory_manager_,
+ *this, channel_state_} {}
DmaPusher::~DmaPusher() = default;
@@ -21,8 +24,6 @@ MICROPROFILE_DEFINE(DispatchCalls, "GPU", "Execute command buffer", MP_RGB(128,
void DmaPusher::DispatchCalls() {
MICROPROFILE_SCOPE(DispatchCalls);
- gpu.SyncGuestHost();
-
dma_pushbuffer_subindex = 0;
dma_state.is_last_call = true;
@@ -33,7 +34,6 @@ void DmaPusher::DispatchCalls() {
}
}
gpu.FlushCommands();
- gpu.SyncGuestHost();
gpu.OnCommandListEnd();
}
@@ -76,11 +76,11 @@ bool DmaPusher::Step() {
// Push buffer non-empty, read a word
command_headers.resize(command_list_header.size);
if (Settings::IsGPULevelHigh()) {
- gpu.MemoryManager().ReadBlock(dma_get, command_headers.data(),
- command_list_header.size * sizeof(u32));
+ memory_manager.ReadBlock(dma_get, command_headers.data(),
+ command_list_header.size * sizeof(u32));
} else {
- gpu.MemoryManager().ReadBlockUnsafe(dma_get, command_headers.data(),
- command_list_header.size * sizeof(u32));
+ memory_manager.ReadBlockUnsafe(dma_get, command_headers.data(),
+ command_list_header.size * sizeof(u32));
}
}
for (std::size_t index = 0; index < command_headers.size();) {
@@ -154,7 +154,7 @@ void DmaPusher::SetState(const CommandHeader& command_header) {
void DmaPusher::CallMethod(u32 argument) const {
if (dma_state.method < non_puller_methods) {
- gpu.CallMethod(GPU::MethodCall{
+ puller.CallPullerMethod(Engines::Puller::MethodCall{
dma_state.method,
argument,
dma_state.subchannel,
@@ -168,12 +168,16 @@ void DmaPusher::CallMethod(u32 argument) const {
void DmaPusher::CallMultiMethod(const u32* base_start, u32 num_methods) const {
if (dma_state.method < non_puller_methods) {
- gpu.CallMultiMethod(dma_state.method, dma_state.subchannel, base_start, num_methods,
- dma_state.method_count);
+ puller.CallMultiMethod(dma_state.method, dma_state.subchannel, base_start, num_methods,
+ dma_state.method_count);
} else {
subchannels[dma_state.subchannel]->CallMultiMethod(dma_state.method, base_start,
num_methods, dma_state.method_count);
}
}
+void DmaPusher::BindRasterizer(VideoCore::RasterizerInterface* rasterizer) {
+ puller.BindRasterizer(rasterizer);
+}
+
} // namespace Tegra
diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h
index 872fd146a..938f0f11c 100644
--- a/src/video_core/dma_pusher.h
+++ b/src/video_core/dma_pusher.h
@@ -10,6 +10,7 @@
#include "common/bit_field.h"
#include "common/common_types.h"
#include "video_core/engines/engine_interface.h"
+#include "video_core/engines/puller.h"
namespace Core {
class System;
@@ -17,7 +18,12 @@ class System;
namespace Tegra {
+namespace Control {
+struct ChannelState;
+}
+
class GPU;
+class MemoryManager;
enum class SubmissionMode : u32 {
IncreasingOld = 0,
@@ -31,24 +37,32 @@ enum class SubmissionMode : u32 {
// Note that, traditionally, methods are treated as 4-byte addressable locations, and hence
// their numbers are written down multiplied by 4 in Docs. Here we are not multiply by 4.
// So the values you see in docs might be multiplied by 4.
+// Register documentation:
+// https://github.com/NVIDIA/open-gpu-doc/blob/ab27fc22db5de0d02a4cabe08e555663b62db4d4/classes/host/cla26f.h
+//
+// Register Description (approx):
+// https://github.com/NVIDIA/open-gpu-doc/blob/ab27fc22db5de0d02a4cabe08e555663b62db4d4/manuals/volta/gv100/dev_pbdma.ref.txt
enum class BufferMethods : u32 {
BindObject = 0x0,
+ Illegal = 0x1,
Nop = 0x2,
SemaphoreAddressHigh = 0x4,
SemaphoreAddressLow = 0x5,
- SemaphoreSequence = 0x6,
- SemaphoreTrigger = 0x7,
- NotifyIntr = 0x8,
+ SemaphoreSequencePayload = 0x6,
+ SemaphoreOperation = 0x7,
+ NonStallInterrupt = 0x8,
WrcacheFlush = 0x9,
- Unk28 = 0xA,
- UnkCacheFlush = 0xB,
+ MemOpA = 0xA,
+ MemOpB = 0xB,
+ MemOpC = 0xC,
+ MemOpD = 0xD,
RefCnt = 0x14,
SemaphoreAcquire = 0x1A,
SemaphoreRelease = 0x1B,
- FenceValue = 0x1C,
- FenceAction = 0x1D,
- WaitForInterrupt = 0x1E,
- Unk7c = 0x1F,
+ SyncpointPayload = 0x1C,
+ SyncpointOperation = 0x1D,
+ WaitForIdle = 0x1E,
+ CRCCheck = 0x1F,
Yield = 0x20,
NonPullerMethods = 0x40,
};
@@ -102,7 +116,8 @@ struct CommandList final {
*/
class DmaPusher final {
public:
- explicit DmaPusher(Core::System& system_, GPU& gpu_);
+ explicit DmaPusher(Core::System& system_, GPU& gpu_, MemoryManager& memory_manager_,
+ Control::ChannelState& channel_state_);
~DmaPusher();
void Push(CommandList&& entries) {
@@ -115,6 +130,8 @@ public:
subchannels[subchannel_id] = engine;
}
+ void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
+
private:
static constexpr u32 non_puller_methods = 0x40;
static constexpr u32 max_subchannels = 8;
@@ -148,6 +165,8 @@ private:
GPU& gpu;
Core::System& system;
+ MemoryManager& memory_manager;
+ mutable Engines::Puller puller;
};
} // namespace Tegra
diff --git a/src/video_core/engines/engine_upload.cpp b/src/video_core/engines/engine_upload.cpp
index 6ff5b1eca..a34819234 100644
--- a/src/video_core/engines/engine_upload.cpp
+++ b/src/video_core/engines/engine_upload.cpp
@@ -3,6 +3,7 @@
#include <cstring>
+#include "common/algorithm.h"
#include "common/assert.h"
#include "video_core/engines/engine_upload.h"
#include "video_core/memory_manager.h"
@@ -34,21 +35,48 @@ void State::ProcessData(const u32 data, const bool is_last_call) {
if (!is_last_call) {
return;
}
+ ProcessData(inner_buffer);
+}
+
+void State::ProcessData(const u32* data, size_t num_data) {
+ std::span<const u8> read_buffer(reinterpret_cast<const u8*>(data), num_data * sizeof(u32));
+ ProcessData(read_buffer);
+}
+
+void State::ProcessData(std::span<const u8> read_buffer) {
const GPUVAddr address{regs.dest.Address()};
if (is_linear) {
- rasterizer->AccelerateInlineToMemory(address, copy_size, inner_buffer);
+ if (regs.line_count == 1) {
+ rasterizer->AccelerateInlineToMemory(address, copy_size, read_buffer);
+ } else {
+ for (u32 line = 0; line < regs.line_count; ++line) {
+ const GPUVAddr dest_line = address + static_cast<size_t>(line) * regs.dest.pitch;
+ memory_manager.WriteBlockUnsafe(
+ dest_line, read_buffer.data() + static_cast<size_t>(line) * regs.line_length_in,
+ regs.line_length_in);
+ }
+ memory_manager.InvalidateRegion(address, regs.dest.pitch * regs.line_count);
+ }
} else {
- UNIMPLEMENTED_IF(regs.dest.z != 0);
- UNIMPLEMENTED_IF(regs.dest.depth != 1);
- UNIMPLEMENTED_IF(regs.dest.BlockWidth() != 0);
- UNIMPLEMENTED_IF(regs.dest.BlockDepth() != 0);
+ u32 width = regs.dest.width;
+ u32 x_elements = regs.line_length_in;
+ u32 x_offset = regs.dest.x;
+ const u32 bpp_shift = Common::FoldRight(
+ 4U, [](u32 x, u32 y) { return std::min(x, static_cast<u32>(std::countr_zero(y))); },
+ width, x_elements, x_offset, static_cast<u32>(address));
+ width >>= bpp_shift;
+ x_elements >>= bpp_shift;
+ x_offset >>= bpp_shift;
+ const u32 bytes_per_pixel = 1U << bpp_shift;
const std::size_t dst_size = Tegra::Texture::CalculateSize(
- true, 1, regs.dest.width, regs.dest.height, 1, regs.dest.BlockHeight(), 0);
+ true, bytes_per_pixel, width, regs.dest.height, regs.dest.depth,
+ regs.dest.BlockHeight(), regs.dest.BlockDepth());
tmp_buffer.resize(dst_size);
memory_manager.ReadBlock(address, tmp_buffer.data(), dst_size);
- Tegra::Texture::SwizzleKepler(regs.dest.width, regs.dest.height, regs.dest.x, regs.dest.y,
- regs.dest.BlockHeight(), copy_size, inner_buffer.data(),
- tmp_buffer.data());
+ Tegra::Texture::SwizzleSubrect(tmp_buffer, read_buffer, bytes_per_pixel, width,
+ regs.dest.height, regs.dest.depth, x_offset, regs.dest.y,
+ x_elements, regs.line_count, regs.dest.BlockHeight(),
+ regs.dest.BlockDepth(), regs.line_length_in);
memory_manager.WriteBlock(address, tmp_buffer.data(), dst_size);
}
}
diff --git a/src/video_core/engines/engine_upload.h b/src/video_core/engines/engine_upload.h
index 94ff3314a..f08f6e36a 100644
--- a/src/video_core/engines/engine_upload.h
+++ b/src/video_core/engines/engine_upload.h
@@ -3,6 +3,7 @@
#pragma once
+#include <span>
#include <vector>
#include "common/bit_field.h"
#include "common/common_types.h"
@@ -33,7 +34,7 @@ struct Registers {
u32 width;
u32 height;
u32 depth;
- u32 z;
+ u32 layer;
u32 x;
u32 y;
@@ -62,11 +63,14 @@ public:
void ProcessExec(bool is_linear_);
void ProcessData(u32 data, bool is_last_call);
+ void ProcessData(const u32* data, size_t num_data);
/// Binds a rasterizer to this engine.
void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
private:
+ void ProcessData(std::span<const u8> read_buffer);
+
u32 write_offset = 0;
u32 copy_size = 0;
std::vector<u8> inner_buffer;
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp
index 5db254d94..7c50bdbe0 100644
--- a/src/video_core/engines/kepler_compute.cpp
+++ b/src/video_core/engines/kepler_compute.cpp
@@ -36,8 +36,6 @@ void KeplerCompute::CallMethod(u32 method, u32 method_argument, bool is_last_cal
}
case KEPLER_COMPUTE_REG_INDEX(data_upload): {
upload_state.ProcessData(method_argument, is_last_call);
- if (is_last_call) {
- }
break;
}
case KEPLER_COMPUTE_REG_INDEX(launch):
@@ -50,8 +48,15 @@ void KeplerCompute::CallMethod(u32 method, u32 method_argument, bool is_last_cal
void KeplerCompute::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
u32 methods_pending) {
- for (std::size_t i = 0; i < amount; i++) {
- CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1);
+ switch (method) {
+ case KEPLER_COMPUTE_REG_INDEX(data_upload):
+ upload_state.ProcessData(base_start, static_cast<size_t>(amount));
+ return;
+ default:
+ for (std::size_t i = 0; i < amount; i++) {
+ CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1);
+ }
+ break;
}
}
diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp
index e2b029542..a3fbab1e5 100644
--- a/src/video_core/engines/kepler_memory.cpp
+++ b/src/video_core/engines/kepler_memory.cpp
@@ -33,8 +33,6 @@ void KeplerMemory::CallMethod(u32 method, u32 method_argument, bool is_last_call
}
case KEPLERMEMORY_REG_INDEX(data): {
upload_state.ProcessData(method_argument, is_last_call);
- if (is_last_call) {
- }
break;
}
}
@@ -42,8 +40,15 @@ void KeplerMemory::CallMethod(u32 method, u32 method_argument, bool is_last_call
void KeplerMemory::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
u32 methods_pending) {
- for (std::size_t i = 0; i < amount; i++) {
- CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1);
+ switch (method) {
+ case KEPLERMEMORY_REG_INDEX(data):
+ upload_state.ProcessData(base_start, static_cast<size_t>(amount));
+ return;
+ default:
+ for (std::size_t i = 0; i < amount; i++) {
+ CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1);
+ }
+ break;
}
}
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 3a4646289..f9794dfe4 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -56,37 +56,37 @@ void Maxwell3D::InitializeRegisterDefaults() {
// Doom and Bomberman seems to use the uninitialized registers and just enable blend
// so initialize blend registers with sane values
- regs.blend.equation_rgb = Regs::Blend::Equation::Add;
- regs.blend.factor_source_rgb = Regs::Blend::Factor::One;
- regs.blend.factor_dest_rgb = Regs::Blend::Factor::Zero;
- regs.blend.equation_a = Regs::Blend::Equation::Add;
- regs.blend.factor_source_a = Regs::Blend::Factor::One;
- regs.blend.factor_dest_a = Regs::Blend::Factor::Zero;
- for (auto& blend : regs.independent_blend) {
- blend.equation_rgb = Regs::Blend::Equation::Add;
- blend.factor_source_rgb = Regs::Blend::Factor::One;
- blend.factor_dest_rgb = Regs::Blend::Factor::Zero;
- blend.equation_a = Regs::Blend::Equation::Add;
- blend.factor_source_a = Regs::Blend::Factor::One;
- blend.factor_dest_a = Regs::Blend::Factor::Zero;
- }
- regs.stencil_front_op_fail = Regs::StencilOp::Keep;
- regs.stencil_front_op_zfail = Regs::StencilOp::Keep;
- regs.stencil_front_op_zpass = Regs::StencilOp::Keep;
- regs.stencil_front_func_func = Regs::ComparisonOp::Always;
+ regs.blend.color_op = Regs::Blend::Equation::Add_D3D;
+ regs.blend.color_source = Regs::Blend::Factor::One_D3D;
+ regs.blend.color_dest = Regs::Blend::Factor::Zero_D3D;
+ regs.blend.alpha_op = Regs::Blend::Equation::Add_D3D;
+ regs.blend.alpha_source = Regs::Blend::Factor::One_D3D;
+ regs.blend.alpha_dest = Regs::Blend::Factor::Zero_D3D;
+ for (auto& blend : regs.blend_per_target) {
+ blend.color_op = Regs::Blend::Equation::Add_D3D;
+ blend.color_source = Regs::Blend::Factor::One_D3D;
+ blend.color_dest = Regs::Blend::Factor::Zero_D3D;
+ blend.alpha_op = Regs::Blend::Equation::Add_D3D;
+ blend.alpha_source = Regs::Blend::Factor::One_D3D;
+ blend.alpha_dest = Regs::Blend::Factor::Zero_D3D;
+ }
+ regs.stencil_front_op.fail = Regs::StencilOp::Op::Keep_D3D;
+ regs.stencil_front_op.zfail = Regs::StencilOp::Op::Keep_D3D;
+ regs.stencil_front_op.zpass = Regs::StencilOp::Op::Keep_D3D;
+ regs.stencil_front_op.func = Regs::ComparisonOp::Always_GL;
regs.stencil_front_func_mask = 0xFFFFFFFF;
regs.stencil_front_mask = 0xFFFFFFFF;
regs.stencil_two_side_enable = 1;
- regs.stencil_back_op_fail = Regs::StencilOp::Keep;
- regs.stencil_back_op_zfail = Regs::StencilOp::Keep;
- regs.stencil_back_op_zpass = Regs::StencilOp::Keep;
- regs.stencil_back_func_func = Regs::ComparisonOp::Always;
+ regs.stencil_back_op.fail = Regs::StencilOp::Op::Keep_D3D;
+ regs.stencil_back_op.zfail = Regs::StencilOp::Op::Keep_D3D;
+ regs.stencil_back_op.zpass = Regs::StencilOp::Op::Keep_D3D;
+ regs.stencil_back_op.func = Regs::ComparisonOp::Always_GL;
regs.stencil_back_func_mask = 0xFFFFFFFF;
regs.stencil_back_mask = 0xFFFFFFFF;
- regs.depth_test_func = Regs::ComparisonOp::Always;
- regs.front_face = Regs::FrontFace::CounterClockWise;
- regs.cull_face = Regs::CullFace::Back;
+ regs.depth_test_func = Regs::ComparisonOp::Always_GL;
+ regs.gl_front_face = Regs::FrontFace::CounterClockWise;
+ regs.gl_cull_face = Regs::CullFace::Back;
// TODO(Rodrigo): Most games do not set a point size. I think this is a case of a
// register carrying a default value. Assume it's OpenGL's default (1).
@@ -107,20 +107,25 @@ void Maxwell3D::InitializeRegisterDefaults() {
// NVN games expect these values to be enabled at boot
regs.rasterize_enable = 1;
- regs.rt_separate_frag_data = 1;
+ regs.color_target_mrt_enable = 1;
regs.framebuffer_srgb = 1;
regs.line_width_aliased = 1.0f;
regs.line_width_smooth = 1.0f;
- regs.front_face = Maxwell3D::Regs::FrontFace::ClockWise;
+ regs.gl_front_face = Maxwell3D::Regs::FrontFace::ClockWise;
regs.polygon_mode_back = Maxwell3D::Regs::PolygonMode::Fill;
regs.polygon_mode_front = Maxwell3D::Regs::PolygonMode::Fill;
shadow_state = regs;
- mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_end_gl)] = true;
- mme_inline[MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)] = true;
- mme_inline[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true;
- mme_inline[MAXWELL3D_REG_INDEX(index_array.count)] = true;
+ draw_command[MAXWELL3D_REG_INDEX(draw.end)] = true;
+ draw_command[MAXWELL3D_REG_INDEX(draw.begin)] = true;
+ draw_command[MAXWELL3D_REG_INDEX(vertex_buffer.first)] = true;
+ draw_command[MAXWELL3D_REG_INDEX(vertex_buffer.count)] = true;
+ draw_command[MAXWELL3D_REG_INDEX(index_buffer.first)] = true;
+ draw_command[MAXWELL3D_REG_INDEX(index_buffer.count)] = true;
+ draw_command[MAXWELL3D_REG_INDEX(draw_inline_index)] = true;
+ draw_command[MAXWELL3D_REG_INDEX(inline_index_2x16.even)] = true;
+ draw_command[MAXWELL3D_REG_INDEX(inline_index_4x8.index0)] = true;
}
void Maxwell3D::ProcessMacro(u32 method, const u32* base_start, u32 amount, bool is_last_call) {
@@ -173,77 +178,77 @@ void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argume
case MAXWELL3D_REG_INDEX(shadow_ram_control):
shadow_state.shadow_ram_control = static_cast<Regs::ShadowRamControl>(nonshadow_argument);
return;
- case MAXWELL3D_REG_INDEX(macros.upload_address):
- return macro_engine->ClearCode(regs.macros.upload_address);
- case MAXWELL3D_REG_INDEX(macros.data):
- return macro_engine->AddCode(regs.macros.upload_address, argument);
- case MAXWELL3D_REG_INDEX(macros.bind):
+ case MAXWELL3D_REG_INDEX(load_mme.instruction_ptr):
+ return macro_engine->ClearCode(regs.load_mme.instruction_ptr);
+ case MAXWELL3D_REG_INDEX(load_mme.instruction):
+ return macro_engine->AddCode(regs.load_mme.instruction_ptr, argument);
+ case MAXWELL3D_REG_INDEX(load_mme.start_address):
return ProcessMacroBind(argument);
- case MAXWELL3D_REG_INDEX(firmware[4]):
+ case MAXWELL3D_REG_INDEX(falcon[4]):
return ProcessFirmwareCall4();
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 1:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 2:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 3:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 4:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 5:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 6:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 7:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 8:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 9:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 10:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 11:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 12:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer):
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 1:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 2:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 3:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 4:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 5:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 6:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 7:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 8:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 9:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 10:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 11:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 12:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 13:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 14:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 15:
return ProcessCBData(argument);
- case MAXWELL3D_REG_INDEX(cb_bind[0]):
+ case MAXWELL3D_REG_INDEX(bind_groups[0].raw_config):
return ProcessCBBind(0);
- case MAXWELL3D_REG_INDEX(cb_bind[1]):
+ case MAXWELL3D_REG_INDEX(bind_groups[1].raw_config):
return ProcessCBBind(1);
- case MAXWELL3D_REG_INDEX(cb_bind[2]):
+ case MAXWELL3D_REG_INDEX(bind_groups[2].raw_config):
return ProcessCBBind(2);
- case MAXWELL3D_REG_INDEX(cb_bind[3]):
+ case MAXWELL3D_REG_INDEX(bind_groups[3].raw_config):
return ProcessCBBind(3);
- case MAXWELL3D_REG_INDEX(cb_bind[4]):
+ case MAXWELL3D_REG_INDEX(bind_groups[4].raw_config):
return ProcessCBBind(4);
- case MAXWELL3D_REG_INDEX(draw.vertex_end_gl):
- return DrawArrays();
- case MAXWELL3D_REG_INDEX(small_index):
- regs.index_array.count = regs.small_index.count;
- regs.index_array.first = regs.small_index.first;
+ case MAXWELL3D_REG_INDEX(index_buffer32_first):
+ regs.index_buffer.count = regs.index_buffer32_first.count;
+ regs.index_buffer.first = regs.index_buffer32_first.first;
dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
- return DrawArrays();
- case MAXWELL3D_REG_INDEX(small_index_2):
- regs.index_array.count = regs.small_index_2.count;
- regs.index_array.first = regs.small_index_2.first;
+ return ProcessDraw();
+ case MAXWELL3D_REG_INDEX(index_buffer16_first):
+ regs.index_buffer.count = regs.index_buffer16_first.count;
+ regs.index_buffer.first = regs.index_buffer16_first.first;
dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
- return DrawArrays();
+ return ProcessDraw();
+ case MAXWELL3D_REG_INDEX(index_buffer8_first):
+ regs.index_buffer.count = regs.index_buffer8_first.count;
+ regs.index_buffer.first = regs.index_buffer8_first.first;
+ dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
+ return ProcessDraw();
case MAXWELL3D_REG_INDEX(topology_override):
use_topology_override = true;
return;
- case MAXWELL3D_REG_INDEX(clear_buffers):
+ case MAXWELL3D_REG_INDEX(clear_surface):
return ProcessClearBuffers();
- case MAXWELL3D_REG_INDEX(query.query_get):
+ case MAXWELL3D_REG_INDEX(report_semaphore.query):
return ProcessQueryGet();
- case MAXWELL3D_REG_INDEX(condition.mode):
+ case MAXWELL3D_REG_INDEX(render_enable.mode):
return ProcessQueryCondition();
- case MAXWELL3D_REG_INDEX(counter_reset):
+ case MAXWELL3D_REG_INDEX(clear_report_value):
return ProcessCounterReset();
case MAXWELL3D_REG_INDEX(sync_info):
return ProcessSyncPoint();
- case MAXWELL3D_REG_INDEX(exec_upload):
- return upload_state.ProcessExec(regs.exec_upload.linear != 0);
- case MAXWELL3D_REG_INDEX(data_upload):
+ case MAXWELL3D_REG_INDEX(launch_dma):
+ return upload_state.ProcessExec(regs.launch_dma.memory_layout.Value() ==
+ Regs::LaunchDMA::Layout::Pitch);
+ case MAXWELL3D_REG_INDEX(inline_data):
upload_state.ProcessData(argument, is_last_call);
- if (is_last_call) {
- }
return;
case MAXWELL3D_REG_INDEX(fragment_barrier):
return rasterizer->FragmentBarrier();
- case MAXWELL3D_REG_INDEX(tiled_cache_barrier):
- return rasterizer->TiledCacheBarrier();
}
}
@@ -257,14 +262,13 @@ void Maxwell3D::CallMacroMethod(u32 method, const std::vector<u32>& parameters)
// Execute the current macro.
macro_engine->Execute(macro_positions[entry], parameters);
- if (mme_draw.current_mode != MMEDrawMode::Undefined) {
- FlushMMEInlineDraw();
- }
+
+ ProcessDeferredDraw();
}
void Maxwell3D::CallMethod(u32 method, u32 method_argument, bool is_last_call) {
- // It is an error to write to a register other than the current macro's ARG register before it
- // has finished execution.
+ // It is an error to write to a register other than the current macro's ARG register before
+ // it has finished execution.
if (executing_macro != 0) {
ASSERT(method == executing_macro + 1);
}
@@ -279,9 +283,33 @@ void Maxwell3D::CallMethod(u32 method, u32 method_argument, bool is_last_call) {
ASSERT_MSG(method < Regs::NUM_REGS,
"Invalid Maxwell3D register, increase the size of the Regs structure");
- const u32 argument = ProcessShadowRam(method, method_argument);
- ProcessDirtyRegisters(method, argument);
- ProcessMethodCall(method, argument, method_argument, is_last_call);
+ if (draw_command[method]) {
+ regs.reg_array[method] = method_argument;
+ deferred_draw_method.push_back(method);
+ auto u32_to_u8 = [&](const u32 argument) {
+ inline_index_draw_indexes.push_back(static_cast<u8>(argument & 0x000000ff));
+ inline_index_draw_indexes.push_back(static_cast<u8>((argument & 0x0000ff00) >> 8));
+ inline_index_draw_indexes.push_back(static_cast<u8>((argument & 0x00ff0000) >> 16));
+ inline_index_draw_indexes.push_back(static_cast<u8>((argument & 0xff000000) >> 24));
+ };
+ if (MAXWELL3D_REG_INDEX(draw_inline_index) == method) {
+ u32_to_u8(method_argument);
+ } else if (MAXWELL3D_REG_INDEX(inline_index_2x16.even) == method) {
+ u32_to_u8(regs.inline_index_2x16.even);
+ u32_to_u8(regs.inline_index_2x16.odd);
+ } else if (MAXWELL3D_REG_INDEX(inline_index_4x8.index0) == method) {
+ u32_to_u8(regs.inline_index_4x8.index0);
+ u32_to_u8(regs.inline_index_4x8.index1);
+ u32_to_u8(regs.inline_index_4x8.index2);
+ u32_to_u8(regs.inline_index_4x8.index3);
+ }
+ } else {
+ ProcessDeferredDraw();
+
+ const u32 argument = ProcessShadowRam(method, method_argument);
+ ProcessDirtyRegisters(method, argument);
+ ProcessMethodCall(method, argument, method_argument, is_last_call);
+ }
}
void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
@@ -293,24 +321,27 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
return;
}
switch (method) {
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data):
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 1:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 2:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 3:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 4:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 5:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 6:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 7:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 8:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 9:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 10:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 11:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 12:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 13:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 14:
- case MAXWELL3D_REG_INDEX(const_buffer.cb_data) + 15:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer):
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 1:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 2:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 3:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 4:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 5:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 6:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 7:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 8:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 9:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 10:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 11:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 12:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 13:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 14:
+ case MAXWELL3D_REG_INDEX(const_buffer.buffer) + 15:
ProcessCBMultiData(base_start, amount);
break;
+ case MAXWELL3D_REG_INDEX(inline_data):
+ upload_state.ProcessData(base_start, static_cast<size_t>(amount));
+ return;
default:
for (std::size_t i = 0; i < amount; i++) {
CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1);
@@ -319,54 +350,6 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
}
}
-void Maxwell3D::StepInstance(const MMEDrawMode expected_mode, const u32 count) {
- if (mme_draw.current_mode == MMEDrawMode::Undefined) {
- if (mme_draw.gl_begin_consume) {
- mme_draw.current_mode = expected_mode;
- mme_draw.current_count = count;
- mme_draw.instance_count = 1;
- mme_draw.gl_begin_consume = false;
- mme_draw.gl_end_count = 0;
- }
- return;
- } else {
- if (mme_draw.current_mode == expected_mode && count == mme_draw.current_count &&
- mme_draw.instance_mode && mme_draw.gl_begin_consume) {
- mme_draw.instance_count++;
- mme_draw.gl_begin_consume = false;
- return;
- } else {
- FlushMMEInlineDraw();
- }
- }
- // Tail call in case it needs to retry.
- StepInstance(expected_mode, count);
-}
-
-void Maxwell3D::CallMethodFromMME(u32 method, u32 method_argument) {
- if (mme_inline[method]) {
- regs.reg_array[method] = method_argument;
- if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count) ||
- method == MAXWELL3D_REG_INDEX(index_array.count)) {
- const MMEDrawMode expected_mode = method == MAXWELL3D_REG_INDEX(vertex_buffer.count)
- ? MMEDrawMode::Array
- : MMEDrawMode::Indexed;
- StepInstance(expected_mode, method_argument);
- } else if (method == MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)) {
- mme_draw.instance_mode =
- (regs.draw.instance_next != 0) || (regs.draw.instance_cont != 0);
- mme_draw.gl_begin_consume = true;
- } else {
- mme_draw.gl_end_count++;
- }
- } else {
- if (mme_draw.current_mode != MMEDrawMode::Undefined) {
- FlushMMEInlineDraw();
- }
- CallMethod(method, method_argument, true);
- }
-}
-
void Maxwell3D::ProcessTopologyOverride() {
using PrimitiveTopology = Maxwell3D::Regs::PrimitiveTopology;
using PrimitiveTopologyOverride = Maxwell3D::Regs::PrimitiveTopologyOverride;
@@ -396,46 +379,12 @@ void Maxwell3D::ProcessTopologyOverride() {
}
}
-void Maxwell3D::FlushMMEInlineDraw() {
- LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(),
- regs.vertex_buffer.count);
- ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?");
- ASSERT(mme_draw.instance_count == mme_draw.gl_end_count);
-
- // Both instance configuration registers can not be set at the same time.
- ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont,
- "Illegal combination of instancing parameters");
-
- ProcessTopologyOverride();
-
- const bool is_indexed = mme_draw.current_mode == MMEDrawMode::Indexed;
- if (ShouldExecute()) {
- rasterizer->Draw(is_indexed, true);
- }
-
- // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if
- // the game is trying to draw indexed or direct mode. This needs to be verified on HW still -
- // it's possible that it is incorrect and that there is some other register used to specify the
- // drawing mode.
- if (is_indexed) {
- regs.index_array.count = 0;
- } else {
- regs.vertex_buffer.count = 0;
- }
- mme_draw.current_mode = MMEDrawMode::Undefined;
- mme_draw.current_count = 0;
- mme_draw.instance_count = 0;
- mme_draw.instance_mode = false;
- mme_draw.gl_begin_consume = false;
- mme_draw.gl_end_count = 0;
-}
-
void Maxwell3D::ProcessMacroUpload(u32 data) {
- macro_engine->AddCode(regs.macros.upload_address++, data);
+ macro_engine->AddCode(regs.load_mme.instruction_ptr++, data);
}
void Maxwell3D::ProcessMacroBind(u32 data) {
- macro_positions[regs.macros.entry++] = data;
+ macro_positions[regs.load_mme.start_address_ptr++] = data;
}
void Maxwell3D::ProcessFirmwareCall4() {
@@ -443,22 +392,14 @@ void Maxwell3D::ProcessFirmwareCall4() {
// Firmware call 4 is a blob that changes some registers depending on its parameters.
// These registers don't affect emulation and so are stubbed by setting 0xd00 to 1.
- regs.reg_array[0xd00] = 1;
+ regs.shadow_scratch[0] = 1;
}
void Maxwell3D::StampQueryResult(u64 payload, bool long_query) {
- struct LongQueryResult {
- u64_le value;
- u64_le timestamp;
- };
- static_assert(sizeof(LongQueryResult) == 16, "LongQueryResult has wrong size");
- const GPUVAddr sequence_address{regs.query.QueryAddress()};
+ const GPUVAddr sequence_address{regs.report_semaphore.Address()};
if (long_query) {
- // Write the 128-bit result structure in long mode. Note: We emulate an infinitely fast
- // GPU, this command may actually take a while to complete in real hardware due to GPU
- // wait queues.
- LongQueryResult query_result{payload, system.GPU().GetTicks()};
- memory_manager.WriteBlock(sequence_address, &query_result, sizeof(query_result));
+ memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks());
+ memory_manager.Write<u64>(sequence_address, payload);
} else {
memory_manager.Write<u32>(sequence_address, static_cast<u32>(payload));
}
@@ -466,31 +407,45 @@ void Maxwell3D::StampQueryResult(u64 payload, bool long_query) {
void Maxwell3D::ProcessQueryGet() {
// TODO(Subv): Support the other query units.
- if (regs.query.query_get.unit != Regs::QueryUnit::Crop) {
- LOG_DEBUG(HW_GPU, "Units other than CROP are unimplemented");
- }
-
- switch (regs.query.query_get.operation) {
- case Regs::QueryOperation::Release:
- if (regs.query.query_get.fence == 1) {
- rasterizer->SignalSemaphore(regs.query.QueryAddress(), regs.query.query_sequence);
+ if (regs.report_semaphore.query.location != Regs::ReportSemaphore::Location::All) {
+ LOG_DEBUG(HW_GPU, "Locations other than ALL are unimplemented");
+ }
+
+ switch (regs.report_semaphore.query.operation) {
+ case Regs::ReportSemaphore::Operation::Release:
+ if (regs.report_semaphore.query.short_query != 0) {
+ const GPUVAddr sequence_address{regs.report_semaphore.Address()};
+ const u32 payload = regs.report_semaphore.payload;
+ std::function<void()> operation([this, sequence_address, payload] {
+ memory_manager.Write<u32>(sequence_address, payload);
+ });
+ rasterizer->SignalFence(std::move(operation));
} else {
- StampQueryResult(regs.query.query_sequence, regs.query.query_get.short_query == 0);
+ struct LongQueryResult {
+ u64_le value;
+ u64_le timestamp;
+ };
+ const GPUVAddr sequence_address{regs.report_semaphore.Address()};
+ const u32 payload = regs.report_semaphore.payload;
+ [this, sequence_address, payload] {
+ memory_manager.Write<u64>(sequence_address + sizeof(u64), system.GPU().GetTicks());
+ memory_manager.Write<u64>(sequence_address, payload);
+ }();
}
break;
- case Regs::QueryOperation::Acquire:
+ case Regs::ReportSemaphore::Operation::Acquire:
// TODO(Blinkhawk): Under this operation, the GPU waits for the CPU to write a value that
// matches the current payload.
UNIMPLEMENTED_MSG("Unimplemented query operation ACQUIRE");
break;
- case Regs::QueryOperation::Counter:
+ case Regs::ReportSemaphore::Operation::ReportOnly:
if (const std::optional<u64> result = GetQueryResult()) {
// If the query returns an empty optional it means it's cached and deferred.
// In this case we have a non-empty result, so we stamp it immediately.
- StampQueryResult(*result, regs.query.query_get.short_query == 0);
+ StampQueryResult(*result, regs.report_semaphore.query.short_query == 0);
}
break;
- case Regs::QueryOperation::Trap:
+ case Regs::ReportSemaphore::Operation::Trap:
UNIMPLEMENTED_MSG("Unimplemented query operation TRAP");
break;
default:
@@ -500,31 +455,31 @@ void Maxwell3D::ProcessQueryGet() {
}
void Maxwell3D::ProcessQueryCondition() {
- const GPUVAddr condition_address{regs.condition.Address()};
- switch (regs.condition.mode) {
- case Regs::ConditionMode::Always: {
+ const GPUVAddr condition_address{regs.render_enable.Address()};
+ switch (regs.render_enable.mode) {
+ case Regs::RenderEnable::Mode::True: {
execute_on = true;
break;
}
- case Regs::ConditionMode::Never: {
+ case Regs::RenderEnable::Mode::False: {
execute_on = false;
break;
}
- case Regs::ConditionMode::ResNonZero: {
- Regs::QueryCompare cmp;
+ case Regs::RenderEnable::Mode::Conditional: {
+ Regs::ReportSemaphore::Compare cmp;
memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
execute_on = cmp.initial_sequence != 0U && cmp.initial_mode != 0U;
break;
}
- case Regs::ConditionMode::Equal: {
- Regs::QueryCompare cmp;
+ case Regs::RenderEnable::Mode::IfEqual: {
+ Regs::ReportSemaphore::Compare cmp;
memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
execute_on =
cmp.initial_sequence == cmp.current_sequence && cmp.initial_mode == cmp.current_mode;
break;
}
- case Regs::ConditionMode::NotEqual: {
- Regs::QueryCompare cmp;
+ case Regs::RenderEnable::Mode::IfNotEqual: {
+ Regs::ReportSemaphore::Compare cmp;
memory_manager.ReadBlock(condition_address, &cmp, sizeof(cmp));
execute_on =
cmp.initial_sequence != cmp.current_sequence || cmp.initial_mode != cmp.current_mode;
@@ -539,108 +494,73 @@ void Maxwell3D::ProcessQueryCondition() {
}
void Maxwell3D::ProcessCounterReset() {
- switch (regs.counter_reset) {
- case Regs::CounterReset::SampleCnt:
+ switch (regs.clear_report_value) {
+ case Regs::ClearReport::ZPassPixelCount:
rasterizer->ResetCounter(QueryType::SamplesPassed);
break;
default:
- LOG_DEBUG(Render_OpenGL, "Unimplemented counter reset={}", regs.counter_reset);
+ LOG_DEBUG(Render_OpenGL, "Unimplemented counter reset={}", regs.clear_report_value);
break;
}
}
void Maxwell3D::ProcessSyncPoint() {
const u32 sync_point = regs.sync_info.sync_point.Value();
- const u32 increment = regs.sync_info.increment.Value();
- [[maybe_unused]] const u32 cache_flush = regs.sync_info.unknown.Value();
- if (increment) {
- rasterizer->SignalSyncPoint(sync_point);
- }
-}
-
-void Maxwell3D::DrawArrays() {
- LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(),
- regs.vertex_buffer.count);
- ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?");
-
- // Both instance configuration registers can not be set at the same time.
- ASSERT_MSG(!regs.draw.instance_next || !regs.draw.instance_cont,
- "Illegal combination of instancing parameters");
-
- ProcessTopologyOverride();
-
- if (regs.draw.instance_next) {
- // Increment the current instance *before* drawing.
- state.current_instance += 1;
- } else if (!regs.draw.instance_cont) {
- // Reset the current instance to 0.
- state.current_instance = 0;
- }
-
- const bool is_indexed{regs.index_array.count && !regs.vertex_buffer.count};
- if (ShouldExecute()) {
- rasterizer->Draw(is_indexed, false);
- }
-
- // TODO(bunnei): Below, we reset vertex count so that we can use these registers to determine if
- // the game is trying to draw indexed or direct mode. This needs to be verified on HW still -
- // it's possible that it is incorrect and that there is some other register used to specify the
- // drawing mode.
- if (is_indexed) {
- regs.index_array.count = 0;
- } else {
- regs.vertex_buffer.count = 0;
+ const u32 cache_flush = regs.sync_info.clean_l2.Value();
+ if (cache_flush != 0) {
+ rasterizer->InvalidateGPUCache();
}
+ rasterizer->SignalSyncPoint(sync_point);
}
std::optional<u64> Maxwell3D::GetQueryResult() {
- switch (regs.query.query_get.select) {
- case Regs::QuerySelect::Payload:
- return regs.query.query_sequence;
- case Regs::QuerySelect::SamplesPassed:
+ switch (regs.report_semaphore.query.report) {
+ case Regs::ReportSemaphore::Report::Payload:
+ return regs.report_semaphore.payload;
+ case Regs::ReportSemaphore::Report::ZPassPixelCount64:
// Deferred.
- rasterizer->Query(regs.query.QueryAddress(), QueryType::SamplesPassed,
+ rasterizer->Query(regs.report_semaphore.Address(), QueryType::SamplesPassed,
system.GPU().GetTicks());
return std::nullopt;
default:
- LOG_DEBUG(HW_GPU, "Unimplemented query select type {}",
- regs.query.query_get.select.Value());
+ LOG_DEBUG(HW_GPU, "Unimplemented query report type {}",
+ regs.report_semaphore.query.report.Value());
return 1;
}
}
void Maxwell3D::ProcessCBBind(size_t stage_index) {
// Bind the buffer currently in CB_ADDRESS to the specified index in the desired shader stage.
- const auto& bind_data = regs.cb_bind[stage_index];
- auto& buffer = state.shader_stages[stage_index].const_buffers[bind_data.index];
+ const auto& bind_data = regs.bind_groups[stage_index];
+ auto& buffer = state.shader_stages[stage_index].const_buffers[bind_data.shader_slot];
buffer.enabled = bind_data.valid.Value() != 0;
- buffer.address = regs.const_buffer.BufferAddress();
- buffer.size = regs.const_buffer.cb_size;
+ buffer.address = regs.const_buffer.Address();
+ buffer.size = regs.const_buffer.size;
const bool is_enabled = bind_data.valid.Value() != 0;
if (!is_enabled) {
- rasterizer->DisableGraphicsUniformBuffer(stage_index, bind_data.index);
+ rasterizer->DisableGraphicsUniformBuffer(stage_index, bind_data.shader_slot);
return;
}
- const GPUVAddr gpu_addr = regs.const_buffer.BufferAddress();
- const u32 size = regs.const_buffer.cb_size;
- rasterizer->BindGraphicsUniformBuffer(stage_index, bind_data.index, gpu_addr, size);
+ const GPUVAddr gpu_addr = regs.const_buffer.Address();
+ const u32 size = regs.const_buffer.size;
+ rasterizer->BindGraphicsUniformBuffer(stage_index, bind_data.shader_slot, gpu_addr, size);
}
void Maxwell3D::ProcessCBMultiData(const u32* start_base, u32 amount) {
// Write the input value to the current const buffer at the current position.
- const GPUVAddr buffer_address = regs.const_buffer.BufferAddress();
+ const GPUVAddr buffer_address = regs.const_buffer.Address();
ASSERT(buffer_address != 0);
// Don't allow writing past the end of the buffer.
- ASSERT(regs.const_buffer.cb_pos <= regs.const_buffer.cb_size);
+ ASSERT(regs.const_buffer.offset <= regs.const_buffer.size);
- const GPUVAddr address{buffer_address + regs.const_buffer.cb_pos};
+ const GPUVAddr address{buffer_address + regs.const_buffer.offset};
const size_t copy_size = amount * sizeof(u32);
memory_manager.WriteBlock(address, start_base, copy_size);
// Increment the current buffer position.
- regs.const_buffer.cb_pos += static_cast<u32>(copy_size);
+ regs.const_buffer.offset += static_cast<u32>(copy_size);
}
void Maxwell3D::ProcessCBData(u32 value) {
@@ -648,7 +568,8 @@ void Maxwell3D::ProcessCBData(u32 value) {
}
Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
- const GPUVAddr tic_address_gpu{regs.tic.Address() + tic_index * sizeof(Texture::TICEntry)};
+ const GPUVAddr tic_address_gpu{regs.tex_header.Address() +
+ tic_index * sizeof(Texture::TICEntry)};
Texture::TICEntry tic_entry;
memory_manager.ReadBlockUnsafe(tic_address_gpu, &tic_entry, sizeof(Texture::TICEntry));
@@ -657,7 +578,8 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
}
Texture::TSCEntry Maxwell3D::GetTSCEntry(u32 tsc_index) const {
- const GPUVAddr tsc_address_gpu{regs.tsc.Address() + tsc_index * sizeof(Texture::TSCEntry)};
+ const GPUVAddr tsc_address_gpu{regs.tex_sampler.Address() +
+ tsc_index * sizeof(Texture::TSCEntry)};
Texture::TSCEntry tsc_entry;
memory_manager.ReadBlockUnsafe(tsc_address_gpu, &tsc_entry, sizeof(Texture::TSCEntry));
@@ -673,4 +595,90 @@ void Maxwell3D::ProcessClearBuffers() {
rasterizer->Clear();
}
+void Maxwell3D::ProcessDraw(u32 instance_count) {
+ LOG_TRACE(HW_GPU, "called, topology={}, count={}", regs.draw.topology.Value(),
+ regs.vertex_buffer.count);
+
+ ASSERT_MSG(!(regs.index_buffer.count && regs.vertex_buffer.count), "Both indexed and direct?");
+
+ // Both instance configuration registers can not be set at the same time.
+ ASSERT_MSG(regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::First ||
+ regs.draw.instance_id != Maxwell3D::Regs::Draw::InstanceId::Unchanged,
+ "Illegal combination of instancing parameters");
+
+ ProcessTopologyOverride();
+
+ const bool is_indexed = regs.index_buffer.count && !regs.vertex_buffer.count;
+ if (ShouldExecute()) {
+ rasterizer->Draw(is_indexed, instance_count);
+ }
+
+ if (is_indexed) {
+ regs.index_buffer.count = 0;
+ } else {
+ regs.vertex_buffer.count = 0;
+ }
+}
+
+void Maxwell3D::ProcessDeferredDraw() {
+ if (deferred_draw_method.empty()) {
+ return;
+ }
+
+ enum class DrawMode {
+ Undefined,
+ General,
+ Instance,
+ };
+ DrawMode draw_mode{DrawMode::Undefined};
+ u32 instance_count = 1;
+
+ u32 index = 0;
+ u32 method = 0;
+ u32 method_count = static_cast<u32>(deferred_draw_method.size());
+ for (; index < method_count &&
+ (method = deferred_draw_method[index]) != MAXWELL3D_REG_INDEX(draw.begin);
+ ++index)
+ ;
+
+ if (MAXWELL3D_REG_INDEX(draw.begin) != method) {
+ return;
+ }
+
+ // The minimum number of methods for drawing must be greater than or equal to
+ // 3[draw.begin->vertex(index)count(first)->draw.end] to avoid errors in index mode drawing
+ if ((method_count - index) < 3) {
+ return;
+ }
+ draw_mode = (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) ||
+ (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Unchanged)
+ ? DrawMode::Instance
+ : DrawMode::General;
+
+ // Drawing will only begin with draw.begin or index_buffer method, other methods directly
+ // clear
+ if (draw_mode == DrawMode::Undefined) {
+ deferred_draw_method.clear();
+ return;
+ }
+
+ if (draw_mode == DrawMode::Instance) {
+ ASSERT_MSG(deferred_draw_method.size() % 4 == 0, "Instance mode method size error");
+ instance_count = static_cast<u32>(method_count - index) / 4;
+ } else {
+ method = deferred_draw_method[index + 1];
+ if (MAXWELL3D_REG_INDEX(draw_inline_index) == method ||
+ MAXWELL3D_REG_INDEX(inline_index_2x16.even) == method ||
+ MAXWELL3D_REG_INDEX(inline_index_4x8.index0) == method) {
+ regs.index_buffer.count = static_cast<u32>(inline_index_draw_indexes.size() / 4);
+ regs.index_buffer.format = Regs::IndexFormat::UnsignedInt;
+ }
+ }
+
+ ProcessDraw(instance_count);
+
+ deferred_draw_method.clear();
+ inline_index_draw_indexes.clear();
+}
+
} // namespace Tegra::Engines
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 5f9eb208c..a948fcb14 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -39,12 +39,15 @@ namespace Tegra::Engines {
/**
* This Engine is known as GF100_3D. Documentation can be found in:
+ * https://github.com/NVIDIA/open-gpu-doc/blob/master/classes/3d/clb197.h
* https://github.com/envytools/envytools/blob/master/rnndb/graph/gf100_3d.xml
* https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h
+ *
+ * Note: nVidia have confirmed that their open docs have had parts redacted, so this list is
+ * currently incomplete, and the gaps are still worth exploring.
*/
-#define MAXWELL3D_REG_INDEX(field_name) \
- (offsetof(Tegra::Engines::Maxwell3D::Regs, field_name) / sizeof(u32))
+#define MAXWELL3D_REG_INDEX(field_name) (offsetof(Maxwell3D::Regs, field_name) / sizeof(u32))
class Maxwell3D final : public EngineInterface {
public:
@@ -55,7 +58,6 @@ public:
void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
/// Register structure of the Maxwell3D engine.
- /// TODO(Subv): This structure will need to be made bigger as more registers are discovered.
struct Regs {
static constexpr std::size_t NUM_REGS = 0xE00;
@@ -74,90 +76,515 @@ public:
static constexpr std::size_t MaxConstBuffers = 18;
static constexpr std::size_t MaxConstBufferSize = 0x10000;
- enum class QueryOperation : u32 {
- Release = 0,
- Acquire = 1,
- Counter = 2,
- Trap = 3,
+ struct ID {
+ union {
+ BitField<0, 16, u32> cls;
+ BitField<16, 5, u32> engine;
+ };
};
- enum class QueryUnit : u32 {
- VFetch = 1,
- VP = 2,
- Rast = 4,
- StrmOut = 5,
- GP = 6,
- ZCull = 7,
- Prop = 10,
- Crop = 15,
+ struct LoadMME {
+ u32 instruction_ptr;
+ u32 instruction;
+ u32 start_address_ptr;
+ u32 start_address;
};
- enum class QuerySelect : u32 {
- Payload = 0,
- TimeElapsed = 2,
- TransformFeedbackPrimitivesGenerated = 11,
- PrimitivesGenerated = 18,
- SamplesPassed = 21,
- TransformFeedbackUnknown = 26,
+ struct Notify {
+ u32 address_high;
+ u32 address_low;
+ u32 type;
+
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
};
- struct QueryCompare {
- u32 initial_sequence;
- u32 initial_mode;
- u32 unknown1;
- u32 unknown2;
- u32 current_sequence;
- u32 current_mode;
+ struct PeerSemaphore {
+ u32 address_high;
+ u32 address_low;
+
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
};
- enum class QuerySyncCondition : u32 {
- NotEqual = 0,
- GreaterThan = 1,
+ struct GlobalRender {
+ enum class Mode : u32 {
+ False = 0,
+ True = 1,
+ Conditional = 2,
+ IfEqual = 3,
+ IfNotEqual = 4,
+ };
+ u32 offset_high;
+ u32 offset_low;
+ Mode mode;
+
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(offset_high) << 32) |
+ offset_low);
+ }
};
- enum class ConditionMode : u32 {
- Never = 0,
- Always = 1,
- ResNonZero = 2,
- Equal = 3,
- NotEqual = 4,
+ enum class ReductionOp : u32 {
+ RedAdd = 0,
+ RedMin = 1,
+ RedMax = 2,
+ RedInc = 3,
+ RedDec = 4,
+ RedAnd = 5,
+ RedOr = 6,
+ RedXor = 7,
};
- enum class ShaderProgram : u32 {
- VertexA = 0,
- VertexB = 1,
- TesselationControl = 2,
- TesselationEval = 3,
- Geometry = 4,
- Fragment = 5,
+ struct LaunchDMA {
+ enum class Layout : u32 {
+ Blocklinear = 0,
+ Pitch = 1,
+ };
+
+ enum class CompletionType : u32 {
+ FlushDisable = 0,
+ FlushOnly = 1,
+ Release = 2,
+ };
+
+ union {
+ BitField<0, 1, Layout> memory_layout;
+ BitField<4, 2, CompletionType> completion_type;
+ BitField<8, 2, u32> interrupt_type;
+ BitField<12, 1, u32> sem_size;
+ BitField<1, 1, u32> reduction_enable;
+ BitField<13, 3, ReductionOp> reduction_op;
+ BitField<2, 2, u32> reduction_format;
+ BitField<6, 1, u32> sysmembar_disable;
+ };
+ };
+
+ struct I2M {
+ u32 address_high;
+ u32 address_low;
+ u32 payload;
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ u32 nop0;
+ u32 nop1;
+ u32 nop2;
+ u32 nop3;
+ };
+
+ struct OpportunisticEarlyZ {
+ BitField<0, 5, u32> threshold;
+
+ u32 Threshold() const {
+ switch (threshold) {
+ case 0x0:
+ return 0;
+ case 0x1F:
+ return 0x1F;
+ default:
+ // Thresholds begin at 0x10 (1 << 4)
+ // Threshold is in the range 0x1 to 0x13
+ return 1 << (4 + threshold.Value() - 1);
+ }
+ }
+ };
+
+ struct GeometryShaderDmFifo {
+ union {
+ BitField<0, 13, u32> raster_on;
+ BitField<16, 13, u32> raster_off;
+ BitField<31, 1, u32> spill_enabled;
+ };
+ };
+
+ struct L2CacheControl {
+ enum class EvictPolicy : u32 {
+ First = 0,
+ Normal = 1,
+ Last = 2,
+ };
+
+ union {
+ BitField<4, 2, EvictPolicy> policy;
+ };
+ };
+
+ struct InvalidateShaderCache {
+ union {
+ BitField<0, 1, u32> instruction;
+ BitField<4, 1, u32> data;
+ BitField<12, 1, u32> constant;
+ BitField<1, 1, u32> locks;
+ BitField<2, 1, u32> flush_data;
+ };
+ };
+
+ struct SyncInfo {
+ enum class Condition : u32 {
+ StreamOutWritesDone = 0,
+ RopWritesDone = 1,
+ };
+
+ union {
+ BitField<0, 16, u32> sync_point;
+ BitField<16, 1, u32> clean_l2;
+ BitField<20, 1, Condition> condition;
+ };
+ };
+
+ struct SurfaceClipBlockId {
+ union {
+ BitField<0, 4, u32> block_width;
+ BitField<4, 4, u32> block_height;
+ BitField<8, 4, u32> block_depth;
+ };
+ };
+
+ struct DecompressSurface {
+ union {
+ BitField<0, 3, u32> mrt_select;
+ BitField<4, 16, u32> rt_array_index;
+ };
+ };
+
+ struct ZCullRopBypass {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<4, 1, u32> no_stall;
+ BitField<8, 1, u32> cull_everything;
+ BitField<12, 4, u32> threshold;
+ };
+ };
+
+ struct ZCullSubregion {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<4, 24, u32> normalized_aliquots;
+ };
+ };
+
+ struct RasterBoundingBox {
+ enum class Mode : u32 {
+ BoundingBox = 0,
+ FullViewport = 1,
+ };
+
+ union {
+ BitField<0, 1, Mode> mode;
+ BitField<4, 8, u32> pad;
+ };
+ };
+
+ struct IteratedBlendOptimization {
+ enum class Noop : u32 {
+ Never = 0,
+ SourceRGBA0000 = 1,
+ SourceAlpha = 2,
+ SourceRGBA0001 = 3,
+ };
+
+ union {
+ BitField<0, 1, Noop> noop;
+ };
+ };
+
+ struct ZCullSubregionAllocation {
+ enum class Format : u32 {
+ Z_16x16x2_4x4 = 0,
+ ZS_16x16_4x4 = 1,
+ Z_16x16_4x2 = 2,
+ Z_16x16_2x4 = 3,
+ Z_16x8_4x4 = 4,
+ Z_8x8_4x2 = 5,
+ Z_8x8_2x4 = 6,
+ Z_16x16_4x8 = 7,
+ Z_4x8_2x2 = 8,
+ ZS_16x8_4x2 = 9,
+ ZS_16x8_2x4 = 10,
+ ZS_8x8_2x2 = 11,
+ Z_4x8_1x1 = 12,
+ None = 15,
+ };
+
+ union {
+ BitField<0, 8, u32> id;
+ BitField<8, 16, u32> aliquots;
+ BitField<24, 4, Format> format;
+ };
+ };
+
+ enum class ZCullSubregionAlgorithm : u32 {
+ Static = 0,
+ Adaptive = 1,
+ };
+
+ struct PixelShaderOutputSampleMaskUsage {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<1, 1, u32> qualify_by_aa;
+ };
+ };
+
+ struct L1Configuration {
+ enum class AddressableMemory : u32 {
+ Size16Kb = 0,
+ Size48Kb = 3,
+ };
+ union {
+ BitField<0, 3, AddressableMemory> direct_addressable_memory;
+ };
+ };
+
+ struct SPAVersion {
+ union {
+ BitField<0, 8, u32> minor;
+ BitField<8, 8, u32> major;
+ };
+ };
+
+ struct SnapGrid {
+ enum class Location : u32 {
+ Pixel2x2 = 1,
+ Pixel4x4 = 2,
+ Pixel8x8 = 3,
+ Pixel16x16 = 4,
+ Pixel32x32 = 5,
+ Pixel64x64 = 6,
+ Pixel128x128 = 7,
+ Pixel256x256 = 8,
+ };
+
+ enum class Mode : u32 {
+ RTNE = 0,
+ Tesla = 1,
+ };
+
+ struct {
+ union {
+ BitField<0, 4, Location> location;
+ BitField<8, 1, Mode> rounding_mode;
+ };
+ } line;
+
+ struct {
+ union {
+ BitField<0, 4, Location> location;
+ BitField<8, 1, Mode> rounding_mode;
+ };
+ } non_line;
+ };
+
+ struct Tessellation {
+ enum class DomainType : u32 {
+ Isolines = 0,
+ Triangles = 1,
+ Quads = 2,
+ };
+
+ enum class Spacing : u32 {
+ Integer = 0,
+ FractionalOdd = 1,
+ FractionalEven = 2,
+ };
+
+ enum class OutputPrimitives : u32 {
+ Points = 0,
+ Lines = 1,
+ Triangles_CW = 2,
+ Triangles_CCW = 3,
+ };
+
+ struct Parameters {
+ union {
+ BitField<0, 2, DomainType> domain_type;
+ BitField<4, 2, Spacing> spacing;
+ BitField<8, 2, OutputPrimitives> output_primitives;
+ };
+ } params;
+
+ struct LOD {
+ std::array<f32, 4> outer;
+ std::array<f32, 2> inner;
+ } lod;
+
+ std::array<u32, 9> reserved;
+ };
+
+ struct SubTilingPerf {
+ struct {
+ union {
+ BitField<0, 8, u32> spm_triangle_register_file_per;
+ BitField<8, 8, u32> spm_pixel_output_buffer_per;
+ BitField<16, 8, u32> spm_triangle_ram_per;
+ BitField<24, 8, u32> max_quads_per;
+ };
+ } knob_a;
+
+ struct {
+ union {
+ BitField<0, 8, u32> max_primitives_per;
+ };
+ } knob_b;
+
+ u32 knob_c;
+ };
+
+ struct ZCullSubregionReport {
+ enum class ReportType : u32 {
+ DepthTest = 0,
+ DepthTestNoAccept = 1,
+ DepthTestLateZ = 2,
+ StencilTest = 3,
+ };
+
+ union {
+ BitField<0, 1, u32> enabled;
+ BitField<4, 8, u32> subregion_id;
+ } to_report;
+
+ union {
+ BitField<0, 1, u32> enabled;
+ BitField<4, 3, ReportType> type;
+ } report_type;
+ };
+
+ struct BalancedPrimitiveWorkload {
+ union {
+ BitField<0, 1, u32> unpartitioned_mode;
+ BitField<4, 1, u32> timesliced_mode;
+ };
+ };
+
+ struct TransformFeedback {
+ struct Buffer {
+ u32 enable;
+ u32 address_high;
+ u32 address_low;
+ s32 size;
+ s32 start_offset;
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
+ static_assert(sizeof(Buffer) == 0x20);
+
+ struct Control {
+ u32 stream;
+ u32 varying_count;
+ u32 stride;
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ };
+ static_assert(sizeof(Control) == 0x10);
+
+ std::array<TransformFeedback::Buffer, NumTransformFeedbackBuffers> buffers;
+
+ INSERT_PADDING_BYTES_NOINIT(0x300);
+
+ std::array<TransformFeedback::Control, NumTransformFeedbackBuffers> controls;
+ };
+
+ struct HybridAntiAliasControl {
+ enum class Centroid : u32 {
+ PerFragment = 0,
+ PerPass = 1,
+ };
+ union {
+ BitField<0, 4, u32> passes;
+ BitField<4, 1, Centroid> centroid;
+ BitField<5, 1, u32> passes_extended;
+ };
+ };
+
+ struct ShaderLocalMemory {
+ u32 base_address;
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ u32 address_high;
+ u32 address_low;
+ u32 size_high;
+ u32 size_low;
+ u32 default_size_per_warp;
+
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+
+ u64 Size() const {
+ return (static_cast<u64>(size_high) << 32) | size_low;
+ }
+ };
+
+ struct ZCullRegion {
+ u32 width;
+ u32 height;
+ u32 depth;
+ u32 offset;
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ u32 fetch_streams_once;
+ union {
+ BitField<0, 16, u32> start_aliquot;
+ BitField<16, 16, u32> aliquot_count;
+ } location;
+ u32 aliquots_per_layer;
+ u32 storage_address_high;
+ u32 storage_address_low;
+ u32 storage_limit_address_high;
+ u32 storage_limit_address_low;
+
+ GPUVAddr StorageAddress() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(storage_address_high) << 32) |
+ storage_address_low);
+ }
+ GPUVAddr StorageLimitAddress() const {
+ return static_cast<GPUVAddr>(
+ (static_cast<GPUVAddr>(storage_limit_address_high) << 32) |
+ storage_limit_address_low);
+ }
+ };
+
+ struct ZetaReadOnly {
+ union {
+ BitField<0, 1, u32> enable_z;
+ BitField<4, 1, u32> enable_stencil;
+ };
};
struct VertexAttribute {
enum class Size : u32 {
Invalid = 0x0,
- Size_32_32_32_32 = 0x01,
- Size_32_32_32 = 0x02,
- Size_16_16_16_16 = 0x03,
- Size_32_32 = 0x04,
- Size_16_16_16 = 0x05,
- Size_8_8_8_8 = 0x0a,
- Size_16_16 = 0x0f,
- Size_32 = 0x12,
- Size_8_8_8 = 0x13,
- Size_8_8 = 0x18,
- Size_16 = 0x1b,
- Size_8 = 0x1d,
- Size_10_10_10_2 = 0x30,
- Size_11_11_10 = 0x31,
+ Size_R32_G32_B32_A32 = 0x01,
+ Size_R32_G32_B32 = 0x02,
+ Size_R16_G16_B16_A16 = 0x03,
+ Size_R32_G32 = 0x04,
+ Size_R16_G16_B16 = 0x05,
+ Size_R8_G8_B8_A8 = 0x0A,
+ Size_R16_G16 = 0x0F,
+ Size_R32 = 0x12,
+ Size_R8_G8_B8 = 0x13,
+ Size_R8_G8 = 0x18,
+ Size_R16 = 0x1B,
+ Size_R8 = 0x1D,
+ Size_A2_B10_G10_R10 = 0x30,
+ Size_B10_G11_R11 = 0x31,
+ Size_G8_R8 = 0x32,
+ Size_X8_B8_G8_R8 = 0x33,
+ Size_A8 = 0x34,
};
enum class Type : u32 {
- SignedNorm = 1,
- UnsignedNorm = 2,
- SignedInt = 3,
- UnsignedInt = 4,
- UnsignedScaled = 5,
- SignedScaled = 6,
+ UnusedEnumDoNotUseBecauseItWillGoAway = 0,
+ SNorm = 1,
+ UNorm = 2,
+ SInt = 3,
+ UInt = 4,
+ UScaled = 5,
+ SScaled = 6,
Float = 7,
};
@@ -173,33 +600,36 @@ public:
u32 ComponentCount() const {
switch (size) {
- case Size::Size_32_32_32_32:
+ case Size::Size_R32_G32_B32_A32:
return 4;
- case Size::Size_32_32_32:
+ case Size::Size_R32_G32_B32:
return 3;
- case Size::Size_16_16_16_16:
+ case Size::Size_R16_G16_B16_A16:
return 4;
- case Size::Size_32_32:
+ case Size::Size_R32_G32:
return 2;
- case Size::Size_16_16_16:
+ case Size::Size_R16_G16_B16:
return 3;
- case Size::Size_8_8_8_8:
+ case Size::Size_R8_G8_B8_A8:
+ case Size::Size_X8_B8_G8_R8:
return 4;
- case Size::Size_16_16:
+ case Size::Size_R16_G16:
return 2;
- case Size::Size_32:
+ case Size::Size_R32:
return 1;
- case Size::Size_8_8_8:
+ case Size::Size_R8_G8_B8:
return 3;
- case Size::Size_8_8:
+ case Size::Size_R8_G8:
+ case Size::Size_G8_R8:
return 2;
- case Size::Size_16:
+ case Size::Size_R16:
return 1;
- case Size::Size_8:
+ case Size::Size_R8:
+ case Size::Size_A8:
return 1;
- case Size::Size_10_10_10_2:
+ case Size::Size_A2_B10_G10_R10:
return 4;
- case Size::Size_11_11_10:
+ case Size::Size_B10_G11_R11:
return 3;
default:
ASSERT(false);
@@ -209,33 +639,36 @@ public:
u32 SizeInBytes() const {
switch (size) {
- case Size::Size_32_32_32_32:
+ case Size::Size_R32_G32_B32_A32:
return 16;
- case Size::Size_32_32_32:
+ case Size::Size_R32_G32_B32:
return 12;
- case Size::Size_16_16_16_16:
+ case Size::Size_R16_G16_B16_A16:
return 8;
- case Size::Size_32_32:
+ case Size::Size_R32_G32:
return 8;
- case Size::Size_16_16_16:
+ case Size::Size_R16_G16_B16:
return 6;
- case Size::Size_8_8_8_8:
+ case Size::Size_R8_G8_B8_A8:
+ case Size::Size_X8_B8_G8_R8:
return 4;
- case Size::Size_16_16:
+ case Size::Size_R16_G16:
return 4;
- case Size::Size_32:
+ case Size::Size_R32:
return 4;
- case Size::Size_8_8_8:
+ case Size::Size_R8_G8_B8:
return 3;
- case Size::Size_8_8:
+ case Size::Size_R8_G8:
+ case Size::Size_G8_R8:
return 2;
- case Size::Size_16:
+ case Size::Size_R16:
return 2;
- case Size::Size_8:
+ case Size::Size_R8:
+ case Size::Size_A8:
return 1;
- case Size::Size_10_10_10_2:
+ case Size::Size_A2_B10_G10_R10:
return 4;
- case Size::Size_11_11_10:
+ case Size::Size_B10_G11_R11:
return 4;
default:
ASSERT(false);
@@ -245,34 +678,36 @@ public:
std::string SizeString() const {
switch (size) {
- case Size::Size_32_32_32_32:
+ case Size::Size_R32_G32_B32_A32:
return "32_32_32_32";
- case Size::Size_32_32_32:
+ case Size::Size_R32_G32_B32:
return "32_32_32";
- case Size::Size_16_16_16_16:
+ case Size::Size_R16_G16_B16_A16:
return "16_16_16_16";
- case Size::Size_32_32:
+ case Size::Size_R32_G32:
return "32_32";
- case Size::Size_16_16_16:
+ case Size::Size_R16_G16_B16:
return "16_16_16";
- case Size::Size_8_8_8_8:
+ case Size::Size_R8_G8_B8_A8:
return "8_8_8_8";
- case Size::Size_16_16:
+ case Size::Size_R16_G16:
return "16_16";
- case Size::Size_32:
+ case Size::Size_R32:
return "32";
- case Size::Size_8_8_8:
+ case Size::Size_R8_G8_B8:
return "8_8_8";
- case Size::Size_8_8:
+ case Size::Size_R8_G8:
+ case Size::Size_G8_R8:
return "8_8";
- case Size::Size_16:
+ case Size::Size_R16:
return "16";
- case Size::Size_8:
+ case Size::Size_R8:
+ case Size::Size_A8:
return "8";
- case Size::Size_10_10_10_2:
- return "10_10_10_2";
- case Size::Size_11_11_10:
- return "11_11_10";
+ case Size::Size_A2_B10_G10_R10:
+ return "2_10_10_10";
+ case Size::Size_B10_G11_R11:
+ return "10_11_12";
default:
ASSERT(false);
return {};
@@ -281,17 +716,19 @@ public:
std::string TypeString() const {
switch (type) {
- case Type::SignedNorm:
+ case Type::UnusedEnumDoNotUseBecauseItWillGoAway:
+ return "Unused";
+ case Type::SNorm:
return "SNORM";
- case Type::UnsignedNorm:
+ case Type::UNorm:
return "UNORM";
- case Type::SignedInt:
+ case Type::SInt:
return "SINT";
- case Type::UnsignedInt:
+ case Type::UInt:
return "UINT";
- case Type::UnsignedScaled:
+ case Type::UScaled:
return "USCALED";
- case Type::SignedScaled:
+ case Type::SScaled:
return "SSCALED";
case Type::Float:
return "FLOAT";
@@ -301,7 +738,7 @@ public:
}
bool IsNormalized() const {
- return (type == Type::SignedNorm) || (type == Type::UnsignedNorm);
+ return (type == Type::SNorm) || (type == Type::UNorm);
}
bool IsValid() const {
@@ -312,6 +749,7 @@ public:
return hex < other.hex;
}
};
+ static_assert(sizeof(VertexAttribute) == 0x4);
struct MsaaSampleLocation {
union {
@@ -342,9 +780,96 @@ public:
}
};
- enum class DepthMode : u32 {
- MinusOneToOne = 0,
- ZeroToOne = 1,
+ struct MultisampleCoverageToColor {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<4, 3, u32> target;
+ };
+ };
+
+ struct DecompressZetaSurface {
+ union {
+ BitField<0, 1, u32> z_enable;
+ BitField<4, 1, u32> stencil_enable;
+ };
+ };
+
+ struct ZetaSparse {
+ enum class UnmappedCompare : u32 {
+ Unmapped = 0,
+ FailAlways = 1,
+ };
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<1, 1, UnmappedCompare> unmapped_compare;
+ };
+ };
+
+ struct RtControl {
+ union {
+ BitField<0, 4, u32> count;
+ BitField<4, 3, u32> target0;
+ BitField<7, 3, u32> target1;
+ BitField<10, 3, u32> target2;
+ BitField<13, 3, u32> target3;
+ BitField<16, 3, u32> target4;
+ BitField<19, 3, u32> target5;
+ BitField<22, 3, u32> target6;
+ BitField<25, 3, u32> target7;
+ };
+
+ u32 Map(std::size_t index) const {
+ const std::array<u32, NumRenderTargets> maps{target0, target1, target2, target3,
+ target4, target5, target6, target7};
+ ASSERT(index < maps.size());
+ return maps[index];
+ }
+ };
+
+ struct CompressionThresholdSamples {
+ u32 samples;
+
+ u32 Samples() {
+ if (samples == 0) {
+ return 0;
+ }
+ return 1 << (samples - 1);
+ }
+ };
+
+ struct PixelShaderInterlockControl {
+ enum class TileMode : u32 {
+ NoConflictDetect = 0,
+ DetectSampleConflict = 1,
+ DetectPixelConflict = 2,
+ };
+ enum class TileSize : u32 {
+ Size_16x16 = 0,
+ Size_8x8 = 1,
+ };
+ enum class FragmentOrder : u32 {
+ FragmentOrdered = 0,
+ FragmentUnordered = 1,
+ };
+ union {
+ BitField<0, 2, TileMode> tile_mode;
+ BitField<2, 1, TileSize> tile_size;
+ BitField<3, 1, FragmentOrder> fragment_order;
+ };
+ };
+
+ struct ZetaSize {
+ enum class DimensionControl : u32 {
+ DepthDefinesArray = 0,
+ ArraySizeOne = 1,
+ };
+
+ u32 width;
+ u32 height;
+ union {
+ BitField<0, 16, u32> depth;
+ BitField<16, 1, DimensionControl> dim_control;
+ };
};
enum class PrimitiveTopology : u32 {
@@ -358,15 +883,21 @@ public:
Quads = 0x7,
QuadStrip = 0x8,
Polygon = 0x9,
- LinesAdjacency = 0xa,
- LineStripAdjacency = 0xb,
- TrianglesAdjacency = 0xc,
- TriangleStripAdjacency = 0xd,
- Patches = 0xe,
+ LinesAdjacency = 0xA,
+ LineStripAdjacency = 0xB,
+ TrianglesAdjacency = 0xC,
+ TriangleStripAdjacency = 0xD,
+ Patches = 0xE,
+ };
+
+ struct VertexArray {
+ union {
+ BitField<0, 16, u32> start;
+ BitField<16, 12, u32> count;
+ BitField<28, 3, PrimitiveTopology> topology;
+ };
};
- // Constants as from NVC0_3D_UNK1970_D3D
- // https://gitlab.freedesktop.org/mesa/mesa/-/blob/main/src/gallium/drivers/nouveau/nvc0/nvc0_3d.xml.h#L1598
enum class PrimitiveTopologyOverride : u32 {
None = 0x0,
Points = 0x1,
@@ -374,11 +905,32 @@ public:
LineStrip = 0x3,
Triangles = 0x4,
TriangleStrip = 0x5,
- LinesAdjacency = 0xa,
- LineStripAdjacency = 0xb,
- TrianglesAdjacency = 0xc,
- TriangleStripAdjacency = 0xd,
- Patches = 0xe,
+ LinesAdjacency = 0xA,
+ LineStripAdjacency = 0xB,
+ TrianglesAdjacency = 0xC,
+ TriangleStripAdjacency = 0xD,
+ Patches = 0xE,
+
+ LegacyPoints = 0x1001,
+ LegacyIndexedLines = 0x1002,
+ LegacyIndexedTriangles = 0x1003,
+ LegacyLines = 0x100F,
+ LegacyLineStrip = 0x1010,
+ LegacyIndexedLineStrip = 0x1011,
+ LegacyTriangles = 0x1012,
+ LegacyTriangleStrip = 0x1013,
+ LegacyIndexedTriangleStrip = 0x1014,
+ LegacyTriangleFan = 0x1015,
+ LegacyIndexedTriangleFan = 0x1016,
+ LegacyTriangleFanImm = 0x1017,
+ LegacyLinesImm = 0x1018,
+ LegacyIndexedTriangles2 = 0x101A,
+ LegacyIndexedLines2 = 0x101B,
+ };
+
+ enum class DepthMode : u32 {
+ MinusOneToOne = 0,
+ ZeroToOne = 1,
};
enum class IndexFormat : u32 {
@@ -388,183 +940,143 @@ public:
};
enum class ComparisonOp : u32 {
- // These values are used by Nouveau and most games, they correspond to the OpenGL token
- // values for these operations.
- Never = 0x200,
- Less = 0x201,
- Equal = 0x202,
- LessEqual = 0x203,
- Greater = 0x204,
- NotEqual = 0x205,
- GreaterEqual = 0x206,
- Always = 0x207,
-
- // These values are used by some games, they seem to be NV04 values.
- NeverOld = 1,
- LessOld = 2,
- EqualOld = 3,
- LessEqualOld = 4,
- GreaterOld = 5,
- NotEqualOld = 6,
- GreaterEqualOld = 7,
- AlwaysOld = 8,
- };
-
- enum class LogicOperation : u32 {
- Clear = 0x1500,
- And = 0x1501,
- AndReverse = 0x1502,
- Copy = 0x1503,
- AndInverted = 0x1504,
- NoOp = 0x1505,
- Xor = 0x1506,
- Or = 0x1507,
- Nor = 0x1508,
- Equiv = 0x1509,
- Invert = 0x150A,
- OrReverse = 0x150B,
- CopyInverted = 0x150C,
- OrInverted = 0x150D,
- Nand = 0x150E,
- Set = 0x150F,
- };
-
- enum class StencilOp : u32 {
- Keep = 1,
- Zero = 2,
- Replace = 3,
- Incr = 4,
- Decr = 5,
- Invert = 6,
- IncrWrap = 7,
- DecrWrap = 8,
- KeepOGL = 0x1E00,
- ZeroOGL = 0,
- ReplaceOGL = 0x1E01,
- IncrOGL = 0x1E02,
- DecrOGL = 0x1E03,
- InvertOGL = 0x150A,
- IncrWrapOGL = 0x8507,
- DecrWrapOGL = 0x8508,
- };
-
- enum class CounterReset : u32 {
- SampleCnt = 0x01,
- Unk02 = 0x02,
- Unk03 = 0x03,
- Unk04 = 0x04,
- EmittedPrimitives = 0x10, // Not tested
- Unk11 = 0x11,
- Unk12 = 0x12,
- Unk13 = 0x13,
- Unk15 = 0x15,
- Unk16 = 0x16,
- Unk17 = 0x17,
- Unk18 = 0x18,
- Unk1A = 0x1A,
- Unk1B = 0x1B,
- Unk1C = 0x1C,
- Unk1D = 0x1D,
- Unk1E = 0x1E,
- GeneratedPrimitives = 0x1F,
+ Never_D3D = 1,
+ Less_D3D = 2,
+ Equal_D3D = 3,
+ LessEqual_D3D = 4,
+ Greater_D3D = 5,
+ NotEqual_D3D = 6,
+ GreaterEqual_D3D = 7,
+ Always_D3D = 8,
+
+ Never_GL = 0x200,
+ Less_GL = 0x201,
+ Equal_GL = 0x202,
+ LessEqual_GL = 0x203,
+ Greater_GL = 0x204,
+ NotEqual_GL = 0x205,
+ GreaterEqual_GL = 0x206,
+ Always_GL = 0x207,
+ };
+
+ enum class ClearReport : u32 {
+ ZPassPixelCount = 0x01,
+ ZCullStats = 0x02,
+ StreamingPrimitvesNeededMinusSucceeded = 0x03,
+ AlphaBetaClocks = 0x04,
+ StreamingPrimitivesSucceeded = 0x10,
+ StreamingPrimitivesNeeded = 0x11,
+ VerticesGenerated = 0x12,
+ PrimitivesGenerated = 0x13,
+ VertexShaderInvocations = 0x15,
+ TessellationInitInvocations = 0x16,
+ TessellationShaderInvocations = 0x17,
+ TessellationShaderPrimitivesGenerated = 0x18,
+ GeometryShaderInvocations = 0x1A,
+ GeometryShaderPrimitivesGenerated = 0x1B,
+ ClipperInvocations = 0x1C,
+ ClipperPrimitivesGenerated = 0x1D,
+ PixelShaderInvocations = 0x1E,
+ VtgPrimitivesOut = 0x1F,
};
enum class FrontFace : u32 {
- ClockWise = 0x0900,
- CounterClockWise = 0x0901,
+ ClockWise = 0x900,
+ CounterClockWise = 0x901,
};
enum class CullFace : u32 {
- Front = 0x0404,
- Back = 0x0405,
- FrontAndBack = 0x0408,
+ Front = 0x404,
+ Back = 0x405,
+ FrontAndBack = 0x408,
};
struct Blend {
enum class Equation : u32 {
- Add = 1,
- Subtract = 2,
- ReverseSubtract = 3,
- Min = 4,
- Max = 5,
-
- // These values are used by Nouveau and some games.
- AddGL = 0x8006,
- MinGL = 0x8007,
- MaxGL = 0x8008,
- SubtractGL = 0x800a,
- ReverseSubtractGL = 0x800b
+ Add_D3D = 1,
+ Subtract_D3D = 2,
+ ReverseSubtract_D3D = 3,
+ Min_D3D = 4,
+ Max_D3D = 5,
+
+ Add_GL = 0x8006,
+ Min_GL = 0x8007,
+ Max_GL = 0x8008,
+ Subtract_GL = 0x800A,
+ ReverseSubtract_GL = 0x800B
};
enum class Factor : u32 {
- Zero = 0x1,
- One = 0x2,
- SourceColor = 0x3,
- OneMinusSourceColor = 0x4,
- SourceAlpha = 0x5,
- OneMinusSourceAlpha = 0x6,
- DestAlpha = 0x7,
- OneMinusDestAlpha = 0x8,
- DestColor = 0x9,
- OneMinusDestColor = 0xa,
- SourceAlphaSaturate = 0xb,
- Source1Color = 0x10,
- OneMinusSource1Color = 0x11,
- Source1Alpha = 0x12,
- OneMinusSource1Alpha = 0x13,
- ConstantColor = 0x61,
- OneMinusConstantColor = 0x62,
- ConstantAlpha = 0x63,
- OneMinusConstantAlpha = 0x64,
-
- // These values are used by Nouveau and some games.
- ZeroGL = 0x4000,
- OneGL = 0x4001,
- SourceColorGL = 0x4300,
- OneMinusSourceColorGL = 0x4301,
- SourceAlphaGL = 0x4302,
- OneMinusSourceAlphaGL = 0x4303,
- DestAlphaGL = 0x4304,
- OneMinusDestAlphaGL = 0x4305,
- DestColorGL = 0x4306,
- OneMinusDestColorGL = 0x4307,
- SourceAlphaSaturateGL = 0x4308,
- ConstantColorGL = 0xc001,
- OneMinusConstantColorGL = 0xc002,
- ConstantAlphaGL = 0xc003,
- OneMinusConstantAlphaGL = 0xc004,
- Source1ColorGL = 0xc900,
- OneMinusSource1ColorGL = 0xc901,
- Source1AlphaGL = 0xc902,
- OneMinusSource1AlphaGL = 0xc903,
+ Zero_D3D = 0x1,
+ One_D3D = 0x2,
+ SourceColor_D3D = 0x3,
+ OneMinusSourceColor_D3D = 0x4,
+ SourceAlpha_D3D = 0x5,
+ OneMinusSourceAlpha_D3D = 0x6,
+ DestAlpha_D3D = 0x7,
+ OneMinusDestAlpha_D3D = 0x8,
+ DestColor_D3D = 0x9,
+ OneMinusDestColor_D3D = 0xA,
+ SourceAlphaSaturate_D3D = 0xB,
+ BothSourceAlpha_D3D = 0xC,
+ OneMinusBothSourceAlpha_D3D = 0xD,
+ BlendFactor_D3D = 0xE,
+ OneMinusBlendFactor_D3D = 0xF,
+ Source1Color_D3D = 0x10,
+ OneMinusSource1Color_D3D = 0x11,
+ Source1Alpha_D3D = 0x12,
+ OneMinusSource1Alpha_D3D = 0x13,
+
+ Zero_GL = 0x4000,
+ One_GL = 0x4001,
+ SourceColor_GL = 0x4300,
+ OneMinusSourceColor_GL = 0x4301,
+ SourceAlpha_GL = 0x4302,
+ OneMinusSourceAlpha_GL = 0x4303,
+ DestAlpha_GL = 0x4304,
+ OneMinusDestAlpha_GL = 0x4305,
+ DestColor_GL = 0x4306,
+ OneMinusDestColor_GL = 0x4307,
+ SourceAlphaSaturate_GL = 0x4308,
+ ConstantColor_GL = 0xC001,
+ OneMinusConstantColor_GL = 0xC002,
+ ConstantAlpha_GL = 0xC003,
+ OneMinusConstantAlpha_GL = 0xC004,
+ Source1Color_GL = 0xC900,
+ OneMinusSource1Color_GL = 0xC901,
+ Source1Alpha_GL = 0xC902,
+ OneMinusSource1Alpha_GL = 0xC903,
};
u32 separate_alpha;
- Equation equation_rgb;
- Factor factor_source_rgb;
- Factor factor_dest_rgb;
- Equation equation_a;
- Factor factor_source_a;
- Factor factor_dest_a;
- INSERT_PADDING_WORDS_NOINIT(1);
+ Equation color_op;
+ Factor color_source;
+ Factor color_dest;
+ Equation alpha_op;
+ Factor alpha_source;
+ u32 enable_global_color_key;
+ Factor alpha_dest;
+
+ u32 single_rop_control_enable;
+ u32 enable[NumRenderTargets];
};
- enum class TessellationPrimitive : u32 {
- Isolines = 0,
- Triangles = 1,
- Quads = 2,
- };
-
- enum class TessellationSpacing : u32 {
- Equal = 0,
- FractionalOdd = 1,
- FractionalEven = 2,
+ struct BlendPerTarget {
+ u32 separate_alpha;
+ Blend::Equation color_op;
+ Blend::Factor color_source;
+ Blend::Factor color_dest;
+ Blend::Equation alpha_op;
+ Blend::Factor alpha_source;
+ Blend::Factor alpha_dest;
+ INSERT_PADDING_BYTES_NOINIT(0x4);
};
+ static_assert(sizeof(BlendPerTarget) == 0x20);
enum class PolygonMode : u32 {
- Point = 0x1b00,
- Line = 0x1b01,
- Fill = 0x1b02,
+ Point = 0x1B00,
+ Line = 0x1B01,
+ Fill = 0x1B02,
};
enum class ShadowRamControl : u32 {
@@ -589,18 +1101,22 @@ public:
NegativeW = 7,
};
- enum class SamplerIndex : u32 {
+ enum class SamplerBinding : u32 {
Independently = 0,
- ViaHeaderIndex = 1,
+ ViaHeaderBinding = 1,
};
struct TileMode {
+ enum class DimensionControl : u32 {
+ DepthDefinesArray = 0,
+ DepthDefinesDepth = 1,
+ };
union {
BitField<0, 4, u32> block_width;
BitField<4, 4, u32> block_height;
BitField<8, 4, u32> block_depth;
BitField<12, 1, u32> is_pitch_linear;
- BitField<16, 1, u32> is_3d;
+ BitField<16, 1, DimensionControl> dim_control;
};
};
static_assert(sizeof(TileMode) == 4);
@@ -616,23 +1132,25 @@ public:
BitField<0, 16, u32> depth;
BitField<16, 1, u32> volume;
};
- u32 layer_stride;
+ u32 array_pitch;
u32 base_layer;
- INSERT_PADDING_WORDS_NOINIT(7);
+ u32 mark_ieee_clean;
+ INSERT_PADDING_BYTES_NOINIT(0x18);
GPUVAddr Address() const {
return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
address_low);
}
};
+ static_assert(sizeof(RenderTargetConfig) == 0x40);
struct ColorMask {
union {
u32 raw;
- BitField<0, 4, u32> R;
- BitField<4, 4, u32> G;
- BitField<8, 4, u32> B;
- BitField<12, 4, u32> A;
+ BitField<0, 1, u32> R;
+ BitField<4, 1, u32> G;
+ BitField<8, 1, u32> B;
+ BitField<12, 1, u32> A;
};
};
@@ -643,6 +1161,7 @@ public:
f32 translate_x;
f32 translate_y;
f32 translate_z;
+
union {
u32 raw;
BitField<0, 3, ViewportSwizzle> x;
@@ -650,7 +1169,11 @@ public:
BitField<8, 3, ViewportSwizzle> z;
BitField<12, 3, ViewportSwizzle> w;
} swizzle;
- INSERT_PADDING_WORDS_NOINIT(1);
+
+ union {
+ BitField<0, 5, u32> x;
+ BitField<8, 5, u32> y;
+ } snap_grid_precision;
Common::Rectangle<f32> GetRect() const {
return {
@@ -677,21 +1200,14 @@ public:
return translate_y + std::fabs(scale_y) - GetY();
}
};
+ static_assert(sizeof(ViewportTransform) == 0x20);
- struct ScissorTest {
- u32 enable;
- union {
- BitField<0, 16, u32> min_x;
- BitField<16, 16, u32> max_x;
- };
- union {
- BitField<0, 16, u32> min_y;
- BitField<16, 16, u32> max_y;
+ struct Viewport {
+ enum class PixelCenter : u32 {
+ HalfIntegers = 0,
+ Integers = 1,
};
- u32 fill;
- };
- struct ViewPort {
union {
BitField<0, 16, u32> x;
BitField<16, 16, u32> width;
@@ -703,726 +1219,1816 @@ public:
float depth_range_near;
float depth_range_far;
};
+ static_assert(sizeof(Viewport) == 0x10);
- struct TransformFeedbackBinding {
- u32 buffer_enable;
- u32 address_high;
- u32 address_low;
- s32 buffer_size;
- s32 buffer_offset;
- INSERT_PADDING_WORDS_NOINIT(3);
-
- GPUVAddr Address() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
- address_low);
- }
+ struct Window {
+ union {
+ BitField<0, 16, u32> x_min;
+ BitField<16, 16, u32> x_max;
+ };
+ union {
+ BitField<0, 16, u32> y_min;
+ BitField<16, 16, u32> y_max;
+ };
};
- static_assert(sizeof(TransformFeedbackBinding) == 32);
+ static_assert(sizeof(Window) == 0x8);
- struct TransformFeedbackLayout {
- u32 stream;
- u32 varying_count;
- u32 stride;
- INSERT_PADDING_WORDS_NOINIT(1);
+ struct ClipIdExtent {
+ union {
+ BitField<0, 16, u32> x;
+ BitField<16, 16, u32> width;
+ };
+ union {
+ BitField<0, 16, u32> y;
+ BitField<16, 16, u32> height;
+ };
+ };
+ static_assert(sizeof(ClipIdExtent) == 0x8);
+
+ enum class VisibleCallLimit : u32 {
+ Limit0 = 0,
+ Limit1 = 1,
+ Limit2 = 2,
+ Limit4 = 3,
+ Limit8 = 4,
+ Limit16 = 5,
+ Limit32 = 6,
+ Limit64 = 7,
+ Limit128 = 8,
+ None = 15,
};
- static_assert(sizeof(TransformFeedbackLayout) == 16);
-
- bool IsShaderConfigEnabled(std::size_t index) const {
- // The VertexB is always enabled.
- if (index == static_cast<std::size_t>(Regs::ShaderProgram::VertexB)) {
- return true;
- }
- return shader_config[index].enable != 0;
- }
-
- bool IsShaderConfigEnabled(Regs::ShaderProgram type) const {
- return IsShaderConfigEnabled(static_cast<std::size_t>(type));
- }
-
- union {
- struct {
- INSERT_PADDING_WORDS_NOINIT(0x44);
-
- u32 wait_for_idle;
- struct {
- u32 upload_address;
- u32 data;
- u32 entry;
- u32 bind;
- } macros;
+ struct StatisticsCounter {
+ union {
+ BitField<0, 1, u32> da_vertices;
+ BitField<1, 1, u32> da_primitives;
+ BitField<2, 1, u32> vs_invocations;
+ BitField<3, 1, u32> gs_invocations;
+ BitField<4, 1, u32> gs_primitives;
+ BitField<5, 1, u32> streaming_primitives_succeeded;
+ BitField<6, 1, u32> streaming_primitives_needed;
+ BitField<7, 1, u32> clipper_invocations;
+ BitField<8, 1, u32> clipper_primitives;
+ BitField<9, 1, u32> ps_invocations;
+ BitField<11, 1, u32> ti_invocations;
+ BitField<12, 1, u32> ts_invocations;
+ BitField<13, 1, u32> ts_primitives;
+ BitField<14, 1, u32> total_streaming_primitives_needed_succeeded;
+ BitField<10, 1, u32> vtg_primitives_out;
+ BitField<15, 1, u32> alpha_beta_clocks;
+ };
+ };
- ShadowRamControl shadow_ram_control;
+ struct ClearRect {
+ union {
+ BitField<0, 16, u32> x_min;
+ BitField<16, 16, u32> x_max;
+ };
+ union {
+ BitField<0, 16, u32> y_min;
+ BitField<16, 16, u32> y_max;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x16);
+ struct VertexBuffer {
+ u32 first;
+ u32 count;
+ };
- Upload::Registers upload;
- struct {
- union {
- BitField<0, 1, u32> linear;
- };
- } exec_upload;
+ struct InvalidateShaderCacheNoWFI {
+ union {
+ BitField<0, 1, u32> instruction;
+ BitField<4, 1, u32> global_data;
+ BitField<12, 1, u32> constant;
+ };
+ };
- u32 data_upload;
+ struct ZCullSerialization {
+ enum class Applied : u32 {
+ Always = 0,
+ LateZ = 1,
+ OutOfGamutZ = 2,
+ LateZOrOutOfGamutZ = 3,
+ };
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<4, 2, Applied> applied;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x16);
+ struct ZCullDirFormat {
+ enum class Zdir : u32 {
+ Less = 0,
+ Greater = 1,
+ };
+ enum class Zformat : u32 {
+ MSB = 0,
+ FP = 1,
+ Ztrick = 2,
+ Zf32 = 3,
+ };
- u32 force_early_fragment_tests;
+ union {
+ BitField<0, 16, Zdir> dir;
+ BitField<16, 16, Zformat> format;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2D);
+ struct IteratedBlend {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<1, 1, u32> enable_alpha;
+ };
+ u32 pass_count;
+ };
- struct {
- union {
- BitField<0, 16, u32> sync_point;
- BitField<16, 1, u32> unknown;
- BitField<20, 1, u32> increment;
- };
- } sync_info;
+ struct ZCullCriterion {
+ enum class Sfunc : u32 {
+ Never = 0,
+ Less = 1,
+ Equal = 2,
+ LessOrEqual = 3,
+ Greater = 4,
+ NotEqual = 5,
+ GreaterOrEqual = 6,
+ Always = 7,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x15);
+ union {
+ BitField<0, 8, Sfunc> sfunc;
+ BitField<8, 1, u32> no_invalidate;
+ BitField<9, 1, u32> force_match;
+ BitField<16, 8, u32> sref;
+ BitField<24, 8, u32> smask;
+ };
+ };
- union {
- BitField<0, 2, TessellationPrimitive> prim;
- BitField<4, 2, TessellationSpacing> spacing;
- BitField<8, 1, u32> cw;
- BitField<9, 1, u32> connected;
- } tess_mode;
+ struct LoadIteratedBlend {
+ enum class Test : u32 {
+ False = 0,
+ True = 1,
+ Equal = 2,
+ NotEqual = 3,
+ LessThan = 4,
+ LessOrEqual = 5,
+ Greater = 6,
+ GreaterOrEqual = 7,
+ };
+ enum class Operation : u32 {
+ AddProducts = 0,
+ SubProducts = 1,
+ Min = 2,
+ Max = 3,
+ Reciprocal = 4,
+ Add = 5,
+ Sub = 6,
+ };
+ enum class OperandA : u32 {
+ SrcRGB = 0,
+ DstRGB = 1,
+ SrcAAA = 2,
+ DstAAA = 3,
+ Temp0_RGB = 4,
+ Temp1_RGB = 5,
+ Temp2_RGB = 6,
+ PBR_RGB = 7,
+ };
+ enum class OperandB : u32 {
+ Zero = 0,
+ One = 1,
+ SrcRGB = 2,
+ SrcAAA = 3,
+ OneMinusSrcAAA = 4,
+ DstRGB = 5,
+ DstAAA = 6,
+ OneMinusDstAAA = 7,
+ Temp0_RGB = 9,
+ Temp1_RGB = 10,
+ Temp2_RGB = 11,
+ PBR_RGB = 12,
+ ConstRGB = 13,
+ ZeroATimesB = 14,
+ };
+ enum class Swizzle : u32 {
+ RGB = 0,
+ GBR = 1,
+ RRR = 2,
+ GGG = 3,
+ BBB = 4,
+ RToA = 5,
+ };
+ enum class WriteMask : u32 {
+ RGB = 0,
+ ROnly = 1,
+ GOnly = 2,
+ BOnly = 3,
+ };
+ enum class Pass : u32 {
+ Temp0 = 0,
+ Temp1 = 1,
+ Temp2 = 2,
+ None = 3,
+ };
- std::array<f32, 4> tess_level_outer;
- std::array<f32, 2> tess_level_inner;
+ u32 instruction_ptr;
+ union {
+ BitField<0, 3, Test> test;
+ BitField<3, 3, Operation> operation;
+ BitField<6, 3, u32> const_input;
+ BitField<9, 3, OperandA> operand_a;
+ BitField<12, 4, OperandB> operand_b;
+ BitField<16, 3, OperandA> operand_c;
+ BitField<19, 4, OperandB> operand_d;
+ BitField<23, 3, Swizzle> output_swizzle;
+ BitField<26, 2, WriteMask> output_mask;
+ BitField<28, 2, Pass> output_pass;
+ BitField<31, 1, u32> test_enabled;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x10);
+ struct ScissorTest {
+ u32 enable;
+ union {
+ BitField<0, 16, u32> min_x;
+ BitField<16, 16, u32> max_x;
+ };
+ union {
+ BitField<0, 16, u32> min_y;
+ BitField<16, 16, u32> max_y;
+ };
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ };
+ static_assert(sizeof(ScissorTest) == 0x10);
- u32 rasterize_enable;
+ struct VPCPerf {
+ union {
+ BitField<0, 8, u32> culled_small_lines;
+ BitField<8, 8, u32> culled_small_triangles;
+ BitField<16, 8, u32> nonculled_lines_and_points;
+ BitField<24, 8, u32> nonculled_triangles;
+ };
+ };
- std::array<TransformFeedbackBinding, NumTransformFeedbackBuffers> tfb_bindings;
+ struct ConstantColorRendering {
+ u32 enabled;
+ u32 red;
+ u32 green;
+ u32 blue;
+ u32 alpha;
+ };
- INSERT_PADDING_WORDS_NOINIT(0xC0);
+ struct VertexStreamSubstitute {
+ u32 address_high;
+ u32 address_low;
- std::array<TransformFeedbackLayout, NumTransformFeedbackBuffers> tfb_layouts;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ struct VTGWarpWatermarks {
+ union {
+ BitField<0, 16, u32> low;
+ BitField<16, 16, u32> high;
+ };
+ };
- u32 tfb_enabled;
+ struct SampleMask {
+ struct Target {
+ union {
+ BitField<0, 1, u32> raster_out;
+ BitField<4, 1, u32> color_target;
+ };
+ u32 target;
+ };
+ struct Pos {
+ u32 x0_y0;
+ u32 x1_y0;
+ u32 x0_y1;
+ u32 x1_y1;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2E);
+ enum class NonMultisampledZ : u32 {
+ PerSample = 0,
+ PixelCenter = 1,
+ };
- std::array<RenderTargetConfig, NumRenderTargets> rt;
+ enum class TIRMode : u32 {
+ Disabled = 0,
+ RasterNTargetM = 1,
+ };
- std::array<ViewportTransform, NumViewports> viewport_transform;
+ enum class AntiAliasRaster : u32 {
+ Mode1x1 = 0,
+ Mode2x2 = 2,
+ Mode4x2_D3D = 4,
+ Mode2x1_D3D = 5,
+ Mode4x4 = 6,
+ };
- std::array<ViewPort, NumViewports> viewports;
+ struct SurfaceClipIDMemory {
+ u32 address_high;
+ u32 address_low;
- INSERT_PADDING_WORDS_NOINIT(0x1D);
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- struct {
- u32 first;
- u32 count;
- } vertex_buffer;
+ struct TIRModulation {
+ enum class Component : u32 {
+ None = 0,
+ RGB = 1,
+ AlphaOnly = 2,
+ RGBA = 3,
+ };
+ enum class Function : u32 {
+ Linear = 0,
+ Table = 1,
+ };
+ Component component;
+ Function function;
+ };
- DepthMode depth_mode;
+ struct Zeta {
+ u32 address_high;
+ u32 address_low;
+ Tegra::DepthFormat format;
+ TileMode tile_mode;
+ u32 array_pitch;
- float clear_color[4];
- float clear_depth;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- INSERT_PADDING_WORDS_NOINIT(0x3);
+ struct SurfaceClip {
+ union {
+ BitField<0, 16, u32> x;
+ BitField<16, 16, u32> width;
+ };
+ union {
+ BitField<0, 16, u32> y;
+ BitField<16, 16, u32> height;
+ };
+ };
- s32 clear_stencil;
+ enum class L2CacheControlPolicy : u32 {
+ First = 0,
+ Normal = 1,
+ Last = 2,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ struct L2CacheVAFRequests {
+ union {
+ BitField<0, 1, u32> system_memory_volatile;
+ BitField<4, 2, L2CacheControlPolicy> policy;
+ };
+ };
- PolygonMode polygon_mode_front;
- PolygonMode polygon_mode_back;
+ enum class ViewportMulticast : u32 {
+ ViewportOrder = 0,
+ PrimitiveOrder = 1,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x3);
+ struct TIRModulationCoeff {
+ union {
+ BitField<0, 8, u32> table_v0;
+ BitField<8, 8, u32> table_v1;
+ BitField<16, 8, u32> table_v2;
+ BitField<24, 8, u32> table_v3;
+ };
+ };
+ static_assert(sizeof(TIRModulationCoeff) == 0x4);
- u32 polygon_offset_point_enable;
- u32 polygon_offset_line_enable;
- u32 polygon_offset_fill_enable;
+ struct ReduceColorThreshold {
+ union {
+ BitField<0, 8, u32> all_hit_once;
+ BitField<16, 8, u32> all_covered;
+ };
+ };
- u32 patch_vertices;
+ struct ClearControl {
+ union {
+ BitField<0, 1, u32> respect_stencil_mask;
+ BitField<4, 1, u32> use_clear_rect;
+ BitField<8, 1, u32> use_scissor;
+ BitField<12, 1, u32> use_viewport_clip0;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ struct L2CacheRopNonInterlockedReads {
+ union {
+ BitField<4, 2, L2CacheControlPolicy> policy;
+ };
+ };
- u32 fragment_barrier;
+ struct VertexOutputAttributeSkipMasks {
+ struct Attributes {
+ union {
+ BitField<0, 1, u32> attribute0_comp0;
+ BitField<1, 1, u32> attribute0_comp1;
+ BitField<2, 1, u32> attribute0_comp2;
+ BitField<3, 1, u32> attribute0_comp3;
+ BitField<4, 1, u32> attribute1_comp0;
+ BitField<5, 1, u32> attribute1_comp1;
+ BitField<6, 1, u32> attribute1_comp2;
+ BitField<7, 1, u32> attribute1_comp3;
+ BitField<8, 1, u32> attribute2_comp0;
+ BitField<9, 1, u32> attribute2_comp1;
+ BitField<10, 1, u32> attribute2_comp2;
+ BitField<11, 1, u32> attribute2_comp3;
+ BitField<12, 1, u32> attribute3_comp0;
+ BitField<13, 1, u32> attribute3_comp1;
+ BitField<14, 1, u32> attribute3_comp2;
+ BitField<15, 1, u32> attribute3_comp3;
+ BitField<16, 1, u32> attribute4_comp0;
+ BitField<17, 1, u32> attribute4_comp1;
+ BitField<18, 1, u32> attribute4_comp2;
+ BitField<19, 1, u32> attribute4_comp3;
+ BitField<20, 1, u32> attribute5_comp0;
+ BitField<21, 1, u32> attribute5_comp1;
+ BitField<22, 1, u32> attribute5_comp2;
+ BitField<23, 1, u32> attribute5_comp3;
+ BitField<24, 1, u32> attribute6_comp0;
+ BitField<25, 1, u32> attribute6_comp1;
+ BitField<26, 1, u32> attribute6_comp2;
+ BitField<27, 1, u32> attribute6_comp3;
+ BitField<28, 1, u32> attribute7_comp0;
+ BitField<29, 1, u32> attribute7_comp1;
+ BitField<30, 1, u32> attribute7_comp2;
+ BitField<31, 1, u32> attribute7_comp3;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x7);
+ std::array<Attributes, 2> a;
+ std::array<Attributes, 2> b;
+ };
- std::array<ScissorTest, NumViewports> scissor_test;
+ struct TIRControl {
+ union {
+ BitField<0, 1, u32> z_pass_pixel_count_use_raster_samples;
+ BitField<4, 1, u32> alpha_coverage_use_raster_samples;
+ BitField<1, 1, u32> reduce_coverage;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x15);
+ enum class FillViaTriangleMode : u32 {
+ Disabled = 0,
+ FillAll = 1,
+ FillBoundingBox = 2,
+ };
- s32 stencil_back_func_ref;
- u32 stencil_back_mask;
- u32 stencil_back_func_mask;
+ struct PsTicketDispenserValue {
+ union {
+ BitField<0, 8, u32> index;
+ BitField<8, 16, u32> value;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x5);
+ struct RegisterWatermarks {
+ union {
+ BitField<0, 16, u32> low;
+ BitField<16, 16, u32> high;
+ };
+ };
- u32 invalidate_texture_data_cache;
+ enum class InvalidateCacheLines : u32 {
+ All = 0,
+ One = 1,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ struct InvalidateTextureDataCacheNoWfi {
+ union {
+ BitField<0, 1, InvalidateCacheLines> lines;
+ BitField<4, 22, u32> tag;
+ };
+ };
- u32 tiled_cache_barrier;
+ struct ZCullRegionEnable {
+ union {
+ BitField<0, 1, u32> enable_z;
+ BitField<4, 1, u32> enable_stencil;
+ BitField<1, 1, u32> rect_clear;
+ BitField<2, 1, u32> use_rt_array_index;
+ BitField<5, 16, u32> rt_array_index;
+ BitField<3, 1, u32> make_conservative;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ enum class FillMode : u32 {
+ Point = 1,
+ Wireframe = 2,
+ Solid = 3,
+ };
- u32 color_mask_common;
+ enum class ShadeMode : u32 {
+ Flat = 0x1,
+ Gouraud = 0x2,
+ GL_Flat = 0x1D00,
+ GL_Smooth = 0x1D01,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ enum class AlphaToCoverageDither : u32 {
+ Footprint_1x1 = 0,
+ Footprint_2x2 = 1,
+ Footprint_1x1_Virtual = 2,
+ };
- f32 depth_bounds[2];
+ struct InlineIndex4x8 {
+ union {
+ BitField<0, 30, u32> count;
+ BitField<30, 2, u32> start;
+ };
+ union {
+ BitField<0, 8, u32> index0;
+ BitField<8, 8, u32> index1;
+ BitField<16, 8, u32> index2;
+ BitField<24, 8, u32> index3;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ enum class D3DCullMode : u32 {
+ None = 0,
+ CW = 1,
+ CCW = 2,
+ };
- u32 rt_separate_frag_data;
+ struct BlendColor {
+ f32 r;
+ f32 g;
+ f32 b;
+ f32 a;
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ struct StencilOp {
+ enum class Op : u32 {
+ Keep_D3D = 1,
+ Zero_D3D = 2,
+ Replace_D3D = 3,
+ IncrSaturate_D3D = 4,
+ DecrSaturate_D3D = 5,
+ Invert_D3D = 6,
+ Incr_D3D = 7,
+ Decr_D3D = 8,
+
+ Keep_GL = 0x1E00,
+ Zero_GL = 0,
+ Replace_GL = 0x1E01,
+ IncrSaturate_GL = 0x1E02,
+ DecrSaturate_GL = 0x1E03,
+ Invert_GL = 0x150A,
+ Incr_GL = 0x8507,
+ Decr_GL = 0x8508,
+ };
- u32 multisample_raster_enable;
- u32 multisample_raster_samples;
- std::array<u32, 4> multisample_sample_mask;
+ Op fail;
+ Op zfail;
+ Op zpass;
+ ComparisonOp func;
+ };
- INSERT_PADDING_WORDS_NOINIT(0x5);
+ struct PsSaturate {
+ // Opposite of DepthMode
+ enum class Depth : u32 {
+ ZeroToOne = 0,
+ MinusOneToOne = 1,
+ };
- struct {
- u32 address_high;
- u32 address_low;
- Tegra::DepthFormat format;
- TileMode tile_mode;
- u32 layer_stride;
+ union {
+ BitField<0, 1, u32> output0_enable;
+ BitField<1, 1, Depth> output0_range;
+ BitField<4, 1, u32> output1_enable;
+ BitField<5, 1, Depth> output1_range;
+ BitField<8, 1, u32> output2_enable;
+ BitField<9, 1, Depth> output2_range;
+ BitField<12, 1, u32> output3_enable;
+ BitField<13, 1, Depth> output3_range;
+ BitField<16, 1, u32> output4_enable;
+ BitField<17, 1, Depth> output4_range;
+ BitField<20, 1, u32> output5_enable;
+ BitField<21, 1, Depth> output5_range;
+ BitField<24, 1, u32> output6_enable;
+ BitField<25, 1, Depth> output6_range;
+ BitField<28, 1, u32> output7_enable;
+ BitField<29, 1, Depth> output7_range;
+ };
- GPUVAddr Address() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
- address_low);
- }
- } zeta;
+ bool AnyEnabled() const {
+ return output0_enable || output1_enable || output2_enable || output3_enable ||
+ output4_enable || output5_enable || output6_enable || output7_enable;
+ }
+ };
- struct {
- union {
- BitField<0, 16, u32> x;
- BitField<16, 16, u32> width;
- };
- union {
- BitField<0, 16, u32> y;
- BitField<16, 16, u32> height;
- };
- } render_area;
+ struct WindowOrigin {
+ enum class Mode : u32 {
+ UpperLeft = 0,
+ LowerLeft = 1,
+ };
+ union {
+ BitField<0, 1, Mode> mode;
+ BitField<4, 1, u32> flip_y;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x3F);
+ struct IteratedBlendConstants {
+ u32 r;
+ u32 g;
+ u32 b;
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ };
+ static_assert(sizeof(IteratedBlendConstants) == 0x10);
+ struct UserClip {
+ struct Enable {
union {
- BitField<0, 4, u32> stencil;
- BitField<4, 4, u32> unknown;
- BitField<8, 4, u32> scissor;
- BitField<12, 4, u32> viewport;
- } clear_flags;
-
- INSERT_PADDING_WORDS_NOINIT(0x10);
-
- u32 fill_rectangle;
-
- INSERT_PADDING_WORDS_NOINIT(0x2);
-
- u32 conservative_raster_enable;
-
- INSERT_PADDING_WORDS_NOINIT(0x5);
-
- std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format;
+ u32 raw;
+ BitField<0, 1, u32> plane0;
+ BitField<1, 1, u32> plane1;
+ BitField<2, 1, u32> plane2;
+ BitField<3, 1, u32> plane3;
+ BitField<4, 1, u32> plane4;
+ BitField<5, 1, u32> plane5;
+ BitField<6, 1, u32> plane6;
+ BitField<7, 1, u32> plane7;
+ };
- std::array<MsaaSampleLocation, 4> multisample_sample_locations;
+ bool AnyEnabled() const {
+ return plane0 || plane1 || plane2 || plane3 || plane4 || plane5 || plane6 ||
+ plane7;
+ }
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ struct Op {
+ enum class ClipOrCull : u32 {
+ Clip = 0,
+ Cull = 1,
+ };
union {
- BitField<0, 1, u32> enable;
- BitField<4, 3, u32> target;
- } multisample_coverage_to_color;
-
- INSERT_PADDING_WORDS_NOINIT(0x8);
-
- struct {
- union {
- BitField<0, 4, u32> count;
- BitField<4, 3, u32> map_0;
- BitField<7, 3, u32> map_1;
- BitField<10, 3, u32> map_2;
- BitField<13, 3, u32> map_3;
- BitField<16, 3, u32> map_4;
- BitField<19, 3, u32> map_5;
- BitField<22, 3, u32> map_6;
- BitField<25, 3, u32> map_7;
- };
-
- u32 Map(std::size_t index) const {
- const std::array<u32, NumRenderTargets> maps{map_0, map_1, map_2, map_3,
- map_4, map_5, map_6, map_7};
- ASSERT(index < maps.size());
- return maps[index];
- }
- } rt_control;
-
- INSERT_PADDING_WORDS_NOINIT(0x2);
-
- u32 zeta_width;
- u32 zeta_height;
- union {
- BitField<0, 16, u32> zeta_depth;
- BitField<16, 1, u32> zeta_volume;
+ u32 raw;
+ BitField<0, 1, ClipOrCull> plane0;
+ BitField<4, 1, ClipOrCull> plane1;
+ BitField<8, 1, ClipOrCull> plane2;
+ BitField<12, 1, ClipOrCull> plane3;
+ BitField<16, 1, ClipOrCull> plane4;
+ BitField<20, 1, ClipOrCull> plane5;
+ BitField<24, 1, ClipOrCull> plane6;
+ BitField<28, 1, ClipOrCull> plane7;
};
+ };
+ };
- SamplerIndex sampler_index;
+ struct AntiAliasAlphaControl {
+ union {
+ BitField<0, 1, u32> alpha_to_coverage;
+ BitField<4, 1, u32> alpha_to_one;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ struct RenderEnable {
+ enum class Override : u32 {
+ UseRenderEnable = 0,
+ AlwaysRender = 1,
+ NeverRender = 2,
+ };
- std::array<u32, 8> gp_passthrough_mask;
+ enum class Mode : u32 {
+ False = 0,
+ True = 1,
+ Conditional = 2,
+ IfEqual = 3,
+ IfNotEqual = 4,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1B);
+ u32 address_high;
+ u32 address_low;
+ Mode mode;
- u32 depth_test_enable;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- INSERT_PADDING_WORDS_NOINIT(0x5);
+ struct TexSampler {
+ u32 address_high;
+ u32 address_low;
+ u32 limit;
- u32 independent_blend_enable;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- u32 depth_write_enabled;
+ struct TexHeader {
+ u32 address_high;
+ u32 address_low;
+ u32 limit;
- u32 alpha_test_enabled;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- INSERT_PADDING_WORDS_NOINIT(0x6);
+ enum class ZCullRegionFormat : u32 {
+ Z_4x4 = 0,
+ ZS_4x4 = 1,
+ Z_4x2 = 2,
+ Z_2x4 = 3,
+ Z_16x8_4x4 = 4,
+ Z_8x8_4x2 = 5,
+ Z_8x8_2x4 = 6,
+ Z_16x16_4x8 = 7,
+ Z_4x8_2x2 = 8,
+ ZS_16x8_4x2 = 9,
+ ZS_16x8_2x4 = 10,
+ ZS_8x8_2x2 = 11,
+ Z_4x8_1x1 = 12,
+ };
+
+ struct RtLayer {
+ enum class Control {
+ LayerSelectsLayer = 0,
+ GeometryShaderSelectsLayer = 1,
+ };
+
+ union {
+ BitField<0, 16, u32> layer;
+ BitField<16, 1, u32> control;
+ };
+ };
- u32 d3d_cull_mode;
+ struct InlineIndex2x16 {
+ union {
+ BitField<0, 31, u32> count;
+ BitField<31, 1, u32> start_odd;
+ };
+ union {
+ BitField<0, 16, u32> even;
+ BitField<16, 16, u32> odd;
+ };
+ };
- ComparisonOp depth_test_func;
- float alpha_test_ref;
- ComparisonOp alpha_test_func;
- u32 draw_tfb_stride;
- struct {
- float r;
- float g;
- float b;
- float a;
- } blend_color;
+ struct VertexGlobalBaseOffset {
+ u32 address_high;
+ u32 address_low;
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- struct {
- u32 separate_alpha;
- Blend::Equation equation_rgb;
- Blend::Factor factor_source_rgb;
- Blend::Factor factor_dest_rgb;
- Blend::Equation equation_a;
- Blend::Factor factor_source_a;
- INSERT_PADDING_WORDS_NOINIT(1);
- Blend::Factor factor_dest_a;
+ struct ZCullRegionPixelOffset {
+ u32 width;
+ u32 height;
+ };
- u32 enable_common;
- u32 enable[NumRenderTargets];
- } blend;
+ struct PointSprite {
+ enum class RMode : u32 {
+ Zero = 0,
+ FromR = 1,
+ FromS = 2,
+ };
+ enum class Origin : u32 {
+ Bottom = 0,
+ Top = 1,
+ };
+ enum class Texture : u32 {
+ Passthrough = 0,
+ Generate = 1,
+ };
- u32 stencil_enable;
- StencilOp stencil_front_op_fail;
- StencilOp stencil_front_op_zfail;
- StencilOp stencil_front_op_zpass;
- ComparisonOp stencil_front_func_func;
- s32 stencil_front_func_ref;
- u32 stencil_front_func_mask;
- u32 stencil_front_mask;
+ union {
+ BitField<0, 2, RMode> rmode;
+ BitField<2, 1, Origin> origin;
+ BitField<3, 1, Texture> texture0;
+ BitField<4, 1, Texture> texture1;
+ BitField<5, 1, Texture> texture2;
+ BitField<6, 1, Texture> texture3;
+ BitField<7, 1, Texture> texture4;
+ BitField<8, 1, Texture> texture5;
+ BitField<9, 1, Texture> texture6;
+ BitField<10, 1, Texture> texture7;
+ BitField<11, 1, Texture> texture8;
+ BitField<12, 1, Texture> texture9;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ struct ProgramRegion {
+ u32 address_high;
+ u32 address_low;
- u32 frag_color_clamp;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- union {
- BitField<0, 1, u32> y_negate;
- BitField<4, 1, u32> triangle_rast_flip;
- } screen_y_control;
+ struct DefaultAttributes {
+ enum class Diffuse : u32 {
+ Vector_0001 = 0,
+ Vector_1111 = 1,
+ };
+ enum class Specular : u32 {
+ Vector_0000 = 0,
+ Vector_0001 = 1,
+ };
+ enum class Vector : u32 {
+ Vector_0000 = 0,
+ Vector_0001 = 1,
+ };
+ enum class FixedFncTexture : u32 {
+ Vector_0000 = 0,
+ Vector_0001 = 1,
+ };
+ enum class DX9Color0 : u32 {
+ Vector_0000 = 0,
+ Vector_1111 = 1,
+ };
+ enum class DX9Color1To15 : u32 {
+ Vector_0000 = 0,
+ Vector_0001 = 1,
+ };
- float line_width_smooth;
- float line_width_aliased;
+ union {
+ BitField<0, 1, Diffuse> color_front_diffuse;
+ BitField<1, 1, Specular> color_front_specular;
+ BitField<2, 1, Vector> generic_vector;
+ BitField<3, 1, FixedFncTexture> fixed_fnc_texture;
+ BitField<4, 1, DX9Color0> dx9_color0;
+ BitField<5, 1, DX9Color1To15> dx9_color1_to_15;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1B);
+ struct Draw {
+ enum class PrimitiveId : u32 {
+ First = 0,
+ Unchanged = 1,
+ };
+ enum class InstanceId : u32 {
+ First = 0,
+ Subsequent = 1,
+ Unchanged = 2,
+ };
+ enum class SplitMode : u32 {
+ NormalBeginNormal = 0,
+ NormalBeginOpen = 1,
+ OpenBeginOpen = 2,
+ OpenBeginNormal = 3,
+ };
- u32 invalidate_sampler_cache_no_wfi;
- u32 invalidate_texture_header_cache_no_wfi;
+ u32 end;
+ union {
+ u32 begin;
+ BitField<0, 16, PrimitiveTopology> topology;
+ BitField<24, 1, PrimitiveId> primitive_id;
+ BitField<26, 2, InstanceId> instance_id;
+ BitField<29, 2, SplitMode> split_mode;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x2);
+ struct VertexIdCopy {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<4, 8, u32> attribute_slot;
+ };
+ };
- u32 vb_element_base;
- u32 vb_base_instance;
+ struct ShaderBasedCull {
+ union {
+ BitField<1, 1, u32> batch_cull_enable;
+ BitField<0, 1, u32> before_fetch_enable;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x35);
+ struct ClassVersion {
+ union {
+ BitField<0, 16, u32> current;
+ BitField<16, 16, u32> oldest_supported;
+ };
+ };
- u32 clip_distance_enabled;
+ struct PrimitiveRestart {
+ u32 enabled;
+ u32 index;
+ };
- u32 samplecnt_enable;
+ struct OutputVertexId {
+ union {
+ BitField<12, 1, u32> uses_array_start;
+ };
+ };
- float point_size;
+ enum class PointCenterMode : u32 {
+ GL = 0,
+ D3D = 1,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ enum class LineSmoothParams : u32 {
+ Falloff_1_00 = 0,
+ Falloff_1_33 = 1,
+ Falloff_1_66 = 2,
+ };
- u32 point_sprite_enable;
+ struct LineSmoothEdgeTable {
+ union {
+ BitField<0, 8, u32> v0;
+ BitField<8, 8, u32> v1;
+ BitField<16, 8, u32> v2;
+ BitField<24, 8, u32> v3;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x3);
+ struct LineStippleParams {
+ union {
+ BitField<0, 8, u32> factor;
+ BitField<8, 16, u32> pattern;
+ };
+ };
- CounterReset counter_reset;
+ enum class ProvokingVertex : u32 {
+ First = 0,
+ Last = 1,
+ };
- u32 multisample_enable;
+ struct ShaderControl {
+ enum class Partial : u32 {
+ Zero = 0,
+ Infinity = 1,
+ };
+ enum class FP32NanBehavior : u32 {
+ Legacy = 0,
+ FP64Compatible = 1,
+ };
+ enum class FP32F2INanBehavior : u32 {
+ PassZero = 0,
+ PassIndefinite = 1,
+ };
- u32 zeta_enable;
+ union {
+ BitField<0, 1, Partial> default_partial;
+ BitField<1, 1, FP32NanBehavior> fp32_nan_behavior;
+ BitField<2, 1, FP32F2INanBehavior> fp32_f2i_nan_behavior;
+ };
+ };
- union {
- BitField<0, 1, u32> alpha_to_coverage;
- BitField<4, 1, u32> alpha_to_one;
- } multisample_control;
+ struct SphVersion {
+ union {
+ BitField<0, 16, u32> current;
+ BitField<16, 16, u32> oldest_supported;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ struct AlphaToCoverageOverride {
+ union {
+ BitField<0, 1, u32> qualify_by_anti_alias_enable;
+ BitField<1, 1, u32> qualify_by_ps_sample_mask_enable;
+ };
+ };
- struct {
- u32 address_high;
- u32 address_low;
- ConditionMode mode;
+ struct AamVersion {
+ union {
+ BitField<0, 16, u32> current;
+ BitField<16, 16, u32> oldest_supported;
+ };
+ };
- GPUVAddr Address() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
- address_low);
- }
- } condition;
+ struct IndexBuffer {
+ u32 start_addr_high;
+ u32 start_addr_low;
+ u32 limit_addr_high;
+ u32 limit_addr_low;
+ IndexFormat format;
+ u32 first;
+ u32 count;
+
+ unsigned FormatSizeInBytes() const {
+ switch (format) {
+ case IndexFormat::UnsignedByte:
+ return 1;
+ case IndexFormat::UnsignedShort:
+ return 2;
+ case IndexFormat::UnsignedInt:
+ return 4;
+ }
+ ASSERT(false);
+ return 1;
+ }
- struct {
- u32 address_high;
- u32 address_low;
- u32 limit;
+ GPUVAddr StartAddress() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(start_addr_high) << 32) |
+ start_addr_low);
+ }
- GPUVAddr Address() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
- address_low);
- }
- } tsc;
+ GPUVAddr EndAddress() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_addr_high) << 32) |
+ limit_addr_low);
+ }
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ /// Adjust the index buffer offset so it points to the first desired index.
+ GPUVAddr IndexStart() const {
+ return StartAddress() +
+ static_cast<size_t>(first) * static_cast<size_t>(FormatSizeInBytes());
+ }
+ };
- float polygon_offset_factor;
+ struct IndexBufferSmall {
+ union {
+ BitField<0, 16, u32> first;
+ BitField<16, 12, u32> count;
+ BitField<28, 4, PrimitiveTopology> topology;
+ };
+ };
- u32 line_smooth_enable;
+ struct VertexStreamInstances {
+ std::array<u32, NumVertexArrays> is_instanced;
- struct {
- u32 address_high;
- u32 address_low;
- u32 limit;
+ /// Returns whether the vertex array specified by index is supposed to be
+ /// accessed per instance or not.
+ bool IsInstancingEnabled(std::size_t index) const {
+ return is_instanced[index];
+ }
+ };
- GPUVAddr Address() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
- address_low);
- }
- } tic;
+ struct AttributePointSize {
+ union {
+ BitField<0, 1, u32> enabled;
+ BitField<4, 8, u32> slot;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x5);
+ struct ViewportClipControl {
+ enum class GeometryGuardband : u32 {
+ Scale256 = 0,
+ Scale1 = 1,
+ };
+ enum class GeometryClip : u32 {
+ WZero = 0,
+ Passthrough = 1,
+ FrustumXY = 2,
+ FrustumXYZ = 3,
+ WZeroNoZCull = 4,
+ FrustumZ = 5,
+ WZeroTriFillOrClip = 6,
+ };
+ enum class GeometryGuardbandZ : u32 {
+ SameAsXY = 0,
+ Scale256 = 1,
+ Scale1 = 2,
+ };
- u32 stencil_two_side_enable;
- StencilOp stencil_back_op_fail;
- StencilOp stencil_back_op_zfail;
- StencilOp stencil_back_op_zpass;
- ComparisonOp stencil_back_func_func;
+ union {
+ BitField<0, 1, u32> depth_0_to_1;
+ BitField<3, 1, u32> pixel_min_z;
+ BitField<4, 1, u32> pixel_max_z;
+ BitField<7, 1, GeometryGuardband> geometry_guardband;
+ BitField<11, 3, GeometryClip> geometry_clip;
+ BitField<1, 2, GeometryGuardbandZ> geometry_guardband_z;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ enum class PrimitiveTopologyControl : u32 {
+ UseInBeginMethods = 0,
+ UseSeparateState = 1,
+ };
- u32 framebuffer_srgb;
+ struct WindowClip {
+ enum class Type : u32 {
+ Inclusive = 0,
+ Exclusive = 1,
+ ClipAll = 2,
+ };
- float polygon_offset_units;
+ u32 enable;
+ Type type;
+ };
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ enum class InvalidateZCull : u32 {
+ Invalidate = 0,
+ };
- Tegra::Texture::MsaaMode multisample_mode;
+ struct ZCull {
+ union {
+ BitField<0, 1, u32> z_enable;
+ BitField<1, 1, u32> stencil_enable;
+ };
+ union {
+ BitField<0, 1, u32> z_min_enbounded;
+ BitField<1, 1, u32> z_max_unbounded;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0xC);
+ struct LogicOp {
+ enum class Op : u32 {
+ Clear = 0x1500,
+ And = 0x1501,
+ AndReverse = 0x1502,
+ Copy = 0x1503,
+ AndInverted = 0x1504,
+ NoOp = 0x1505,
+ Xor = 0x1506,
+ Or = 0x1507,
+ Nor = 0x1508,
+ Equiv = 0x1509,
+ Invert = 0x150A,
+ OrReverse = 0x150B,
+ CopyInverted = 0x150C,
+ OrInverted = 0x150D,
+ Nand = 0x150E,
+ Set = 0x150F,
+ };
- union {
- BitField<2, 1, u32> coord_origin;
- BitField<3, 10, u32> enable;
- } point_coord_replace;
-
- struct {
- u32 code_address_high;
- u32 code_address_low;
-
- GPUVAddr CodeAddress() const {
- return static_cast<GPUVAddr>(
- (static_cast<GPUVAddr>(code_address_high) << 32) | code_address_low);
- }
- } code_address;
- INSERT_PADDING_WORDS_NOINIT(1);
-
- struct {
- u32 vertex_end_gl;
- union {
- u32 vertex_begin_gl;
- BitField<0, 16, PrimitiveTopology> topology;
- BitField<26, 1, u32> instance_next;
- BitField<27, 1, u32> instance_cont;
- };
- } draw;
-
- INSERT_PADDING_WORDS_NOINIT(0xA);
-
- struct {
- u32 enabled;
- u32 index;
- } primitive_restart;
-
- INSERT_PADDING_WORDS_NOINIT(0xE);
-
- u32 provoking_vertex_last;
-
- INSERT_PADDING_WORDS_NOINIT(0x50);
-
- struct {
- u32 start_addr_high;
- u32 start_addr_low;
- u32 end_addr_high;
- u32 end_addr_low;
- IndexFormat format;
- u32 first;
- u32 count;
-
- unsigned FormatSizeInBytes() const {
- switch (format) {
- case IndexFormat::UnsignedByte:
- return 1;
- case IndexFormat::UnsignedShort:
- return 2;
- case IndexFormat::UnsignedInt:
- return 4;
- }
- ASSERT(false);
- return 1;
- }
-
- GPUVAddr StartAddress() const {
- return static_cast<GPUVAddr>(
- (static_cast<GPUVAddr>(start_addr_high) << 32) | start_addr_low);
- }
-
- GPUVAddr EndAddress() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(end_addr_high) << 32) |
- end_addr_low);
- }
-
- /// Adjust the index buffer offset so it points to the first desired index.
- GPUVAddr IndexStart() const {
- return StartAddress() + static_cast<size_t>(first) *
- static_cast<size_t>(FormatSizeInBytes());
- }
- } index_array;
+ u32 enable;
+ Op op;
+ };
- union {
- BitField<0, 16, u32> first;
- BitField<16, 16, u32> count;
- } small_index;
+ struct ClearSurface {
+ union {
+ u32 raw;
+ BitField<0, 1, u32> Z;
+ BitField<1, 1, u32> S;
+ BitField<2, 1, u32> R;
+ BitField<3, 1, u32> G;
+ BitField<4, 1, u32> B;
+ BitField<5, 1, u32> A;
+ BitField<6, 4, u32> RT;
+ BitField<10, 16, u32> layer;
+ };
+ };
- union {
- BitField<0, 16, u32> first;
- BitField<16, 16, u32> count;
- } small_index_2;
+ struct ReportSemaphore {
+ struct Compare {
+ u32 initial_sequence;
+ u32 initial_mode;
+ u32 unknown1;
+ u32 unknown2;
+ u32 current_sequence;
+ u32 current_mode;
+ };
- INSERT_PADDING_WORDS_NOINIT(0x5);
+ enum class Operation : u32 {
+ Release = 0,
+ Acquire = 1,
+ ReportOnly = 2,
+ Trap = 3,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x1F);
+ enum class Release : u32 {
+ AfterAllPreceedingReads = 0,
+ AfterAllPreceedingWrites = 1,
+ };
- float polygon_offset_clamp;
+ enum class Acquire : u32 {
+ BeforeAnyFollowingWrites = 0,
+ BeforeAnyFollowingReads = 1,
+ };
- struct {
- u32 is_instanced[NumVertexArrays];
+ enum class Location : u32 {
+ None = 0,
+ VertexFetch = 1,
+ VertexShader = 2,
+ VPC = 4,
+ StreamingOutput = 5,
+ GeometryShader = 6,
+ ZCull = 7,
+ TessellationInit = 8,
+ TessellationShader = 9,
+ PixelShader = 10,
+ DepthTest = 12,
+ All = 15,
+ };
- /// Returns whether the vertex array specified by index is supposed to be
- /// accessed per instance or not.
- bool IsInstancingEnabled(std::size_t index) const {
- return is_instanced[index];
- }
- } instanced_arrays;
+ enum class Comparison : u32 {
+ NotEqual = 0,
+ GreaterOrEqual = 1,
+ };
- INSERT_PADDING_WORDS_NOINIT(0x4);
+ enum class Report : u32 {
+ Payload = 0, // "None" in docs, but confirmed via hardware to return the payload
+ VerticesGenerated = 1,
+ ZPassPixelCount = 2,
+ PrimitivesGenerated = 3,
+ AlphaBetaClocks = 4,
+ VertexShaderInvocations = 5,
+ StreamingPrimitivesNeededMinusSucceeded = 6,
+ GeometryShaderInvocations = 7,
+ GeometryShaderPrimitivesGenerated = 9,
+ ZCullStats0 = 10,
+ StreamingPrimitivesSucceeded = 11,
+ ZCullStats1 = 12,
+ StreamingPrimitivesNeeded = 13,
+ ZCullStats2 = 14,
+ ClipperInvocations = 15,
+ ZCullStats3 = 16,
+ ClipperPrimitivesGenerated = 17,
+ VtgPrimitivesOut = 18,
+ PixelShaderInvocations = 19,
+ ZPassPixelCount64 = 21,
+ IEEECleanColorTarget = 24,
+ IEEECleanZetaTarget = 25,
+ StreamingByteCount = 26,
+ TessellationInitInvocations = 27,
+ BoundingRectangle = 28,
+ TessellationShaderInvocations = 29,
+ TotalStreamingPrimitivesNeededMinusSucceeded = 30,
+ TessellationShaderPrimitivesGenerated = 31,
+ };
- union {
- BitField<0, 1, u32> enable;
- BitField<4, 8, u32> unk4;
- } vp_point_size;
+ u32 address_high;
+ u32 address_low;
+ u32 payload;
+ union {
+ u32 raw;
+ BitField<0, 2, Operation> operation;
+ BitField<4, 1, Release> release;
+ BitField<8, 1, Acquire> acquire;
+ BitField<12, 4, Location> location;
+ BitField<16, 1, Comparison> comparison;
+ BitField<20, 1, u32> awaken_enable;
+ BitField<23, 5, Report> report;
+ BitField<28, 1, u32> short_query;
+ BitField<5, 3, u32> sub_report;
+ BitField<21, 1, u32> dword_number;
+ BitField<2, 1, u32> disable_flush;
+ BitField<3, 1, u32> reduction_enable;
+ BitField<9, 3, ReductionOp> reduction_op;
+ BitField<17, 2, u32> format_signed;
+ } query;
- INSERT_PADDING_WORDS_NOINIT(1);
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- u32 cull_test_enabled;
- FrontFace front_face;
- CullFace cull_face;
+ struct VertexStream {
+ union {
+ BitField<0, 12, u32> stride;
+ BitField<12, 1, u32> enable;
+ };
+ u32 address_high;
+ u32 address_low;
+ u32 frequency;
- u32 pixel_center_integer;
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ bool IsEnabled() const {
+ return enable != 0 && Address() != 0;
+ }
+ };
+ static_assert(sizeof(VertexStream) == 0x10);
- u32 viewport_transform_enabled;
+ struct VertexStreamLimit {
+ u32 address_high;
+ u32 address_low;
- INSERT_PADDING_WORDS_NOINIT(0x3);
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
+ static_assert(sizeof(VertexStreamLimit) == 0x8);
- union {
- BitField<0, 1, u32> depth_range_0_1;
- BitField<3, 1, u32> depth_clamp_near;
- BitField<4, 1, u32> depth_clamp_far;
- BitField<11, 1, u32> depth_clamp_disabled;
- } view_volume_clip_control;
+ enum class ShaderType : u32 {
+ VertexA = 0,
+ VertexB = 1,
+ TessellationInit = 2,
+ Tessellation = 3,
+ Geometry = 4,
+ Pixel = 5,
+ };
- INSERT_PADDING_WORDS_NOINIT(0xC);
+ struct Pipeline {
+ union {
+ BitField<0, 1, u32> enable;
+ BitField<4, 4, ShaderType> program;
+ };
+ u32 offset;
+ u32 reservedA;
+ u32 register_count;
+ u32 binding_group;
+ std::array<u32, 4> reserved;
+ INSERT_PADDING_BYTES_NOINIT(0x1C);
+ };
+ static_assert(sizeof(Pipeline) == 0x40);
- PrimitiveTopologyOverride topology_override;
+ bool IsShaderConfigEnabled(std::size_t index) const {
+ // The VertexB is always enabled.
+ if (index == static_cast<std::size_t>(ShaderType::VertexB)) {
+ return true;
+ }
+ return pipelines[index].enable != 0;
+ }
- INSERT_PADDING_WORDS_NOINIT(0x12);
+ bool IsShaderConfigEnabled(ShaderType type) const {
+ return IsShaderConfigEnabled(static_cast<std::size_t>(type));
+ }
- u32 depth_bounds_enable;
+ struct ConstantBuffer {
+ u32 size;
+ u32 address_high;
+ u32 address_low;
+ u32 offset;
+ std::array<u32, NumCBData> buffer;
- INSERT_PADDING_WORDS_NOINIT(1);
+ GPUVAddr Address() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ };
- struct {
- u32 enable;
- LogicOperation operation;
- } logic_op;
+ struct BindGroup {
+ std::array<u32, 4> reserved;
+ union {
+ u32 raw_config;
+ BitField<0, 1, u32> valid;
+ BitField<4, 5, u32> shader_slot;
+ };
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ };
+ static_assert(sizeof(BindGroup) == 0x20);
- INSERT_PADDING_WORDS_NOINIT(0x1);
+ struct StreamOutLayout {
+ union {
+ BitField<0, 8, u32> attribute0;
+ BitField<8, 8, u32> attribute1;
+ BitField<16, 8, u32> attribute2;
+ BitField<24, 8, u32> attribute3;
+ };
+ };
+ struct ShaderPerformance {
+ struct ControlA {
union {
- u32 raw;
- BitField<0, 1, u32> Z;
- BitField<1, 1, u32> S;
- BitField<2, 1, u32> R;
- BitField<3, 1, u32> G;
- BitField<4, 1, u32> B;
- BitField<5, 1, u32> A;
- BitField<6, 4, u32> RT;
- BitField<10, 11, u32> layer;
- } clear_buffers;
- INSERT_PADDING_WORDS_NOINIT(0xB);
- std::array<ColorMask, NumRenderTargets> color_mask;
- INSERT_PADDING_WORDS_NOINIT(0x38);
-
- struct {
- u32 query_address_high;
- u32 query_address_low;
- u32 query_sequence;
- union {
- u32 raw;
- BitField<0, 2, QueryOperation> operation;
- BitField<4, 1, u32> fence;
- BitField<12, 4, QueryUnit> unit;
- BitField<16, 1, QuerySyncCondition> sync_cond;
- BitField<23, 5, QuerySelect> select;
- BitField<28, 1, u32> short_query;
- } query_get;
-
- GPUVAddr QueryAddress() const {
- return static_cast<GPUVAddr>(
- (static_cast<GPUVAddr>(query_address_high) << 32) | query_address_low);
- }
- } query;
-
- INSERT_PADDING_WORDS_NOINIT(0x3C);
-
- struct {
- union {
- BitField<0, 12, u32> stride;
- BitField<12, 1, u32> enable;
- };
- u32 start_high;
- u32 start_low;
- u32 divisor;
-
- GPUVAddr StartAddress() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(start_high) << 32) |
- start_low);
- }
-
- bool IsEnabled() const {
- return enable != 0 && StartAddress() != 0;
- }
-
- } vertex_array[NumVertexArrays];
-
- Blend independent_blend[NumRenderTargets];
-
- struct {
- u32 limit_high;
- u32 limit_low;
-
- GPUVAddr LimitAddress() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_high) << 32) |
- limit_low);
- }
- } vertex_array_limit[NumVertexArrays];
-
- struct {
- union {
- BitField<0, 1, u32> enable;
- BitField<4, 4, ShaderProgram> program;
- };
- u32 offset;
- INSERT_PADDING_WORDS_NOINIT(14);
- } shader_config[MaxShaderProgram];
-
- INSERT_PADDING_WORDS_NOINIT(0x60);
-
- u32 firmware[0x20];
-
- struct {
- u32 cb_size;
- u32 cb_address_high;
- u32 cb_address_low;
- u32 cb_pos;
- std::array<u32, NumCBData> cb_data;
-
- GPUVAddr BufferAddress() const {
- return static_cast<GPUVAddr>(
- (static_cast<GPUVAddr>(cb_address_high) << 32) | cb_address_low);
- }
- } const_buffer;
-
- INSERT_PADDING_WORDS_NOINIT(0x10);
-
- struct {
- union {
- u32 raw_config;
- BitField<0, 1, u32> valid;
- BitField<4, 5, u32> index;
- };
- INSERT_PADDING_WORDS_NOINIT(7);
- } cb_bind[MaxShaderStage];
-
- INSERT_PADDING_WORDS_NOINIT(0x56);
-
- u32 tex_cb_index;
-
- INSERT_PADDING_WORDS_NOINIT(0x7D);
-
- std::array<std::array<u8, 128>, NumTransformFeedbackBuffers> tfb_varying_locs;
-
- INSERT_PADDING_WORDS_NOINIT(0x298);
-
- struct {
- /// Compressed address of a buffer that holds information about bound SSBOs.
- /// This address is usually bound to c0 in the shaders.
- u32 buffer_address;
-
- GPUVAddr BufferAddress() const {
- return static_cast<GPUVAddr>(buffer_address) << 8;
- }
- } ssbo_info;
+ BitField<0, 2, u32> event0;
+ BitField<2, 3, u32> bit0;
+ BitField<5, 2, u32> event1;
+ BitField<7, 3, u32> bit1;
+ BitField<10, 2, u32> event2;
+ BitField<12, 3, u32> bit2;
+ BitField<15, 2, u32> event3;
+ BitField<17, 3, u32> bit3;
+ BitField<20, 2, u32> event4;
+ BitField<22, 3, u32> bit4;
+ BitField<25, 2, u32> event5;
+ BitField<27, 3, u32> bit5;
+ BitField<30, 2, u32> spare;
+ };
+ };
- INSERT_PADDING_WORDS_NOINIT(0x11);
+ struct ControlB {
+ union {
+ BitField<0, 1, u32> edge;
+ BitField<1, 2, u32> mode;
+ BitField<3, 1, u32> windowed;
+ BitField<4, 16, u32> func;
+ };
+ };
- struct {
- u32 address[MaxShaderStage];
- u32 size[MaxShaderStage];
- } tex_info_buffers;
+ std::array<u32, 8> values_upper;
+ std::array<u32, 8> values;
+ std::array<u32, 8> events;
+ std::array<ControlA, 8> control_a;
+ std::array<ControlB, 8> control_b;
+ u32 trap_control_mask;
+ u32 start_shader_mask;
+ u32 stop_shader_mask;
+ };
- INSERT_PADDING_WORDS_NOINIT(0xCC);
+ // clang-format off
+ union {
+ struct {
+ ID object_id; ///< 0x0000
+ INSERT_PADDING_BYTES_NOINIT(0xFC);
+ u32 nop; ///< 0x0100
+ Notify notify; ///< 0x0104
+ u32 wait_for_idle; ///< 0x0110
+ LoadMME load_mme; ///< 0x0114
+ ShadowRamControl shadow_ram_control; ///< 0x0124
+ PeerSemaphore peer; ///< 0x0128
+ GlobalRender global_render; ///< 0x0130
+ u32 go_idle; ///< 0x013C
+ u32 trigger; ///< 0x0140
+ u32 trigger_wfi; ///< 0x0144
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ u32 instrumentation_method_header; ///< 0x0150
+ u32 instrumentation_method_data; ///< 0x0154
+ INSERT_PADDING_BYTES_NOINIT(0x28);
+ Upload::Registers upload; ///< 0x0180
+ LaunchDMA launch_dma; ///< 0x01B0
+ u32 inline_data; ///< 0x01B4
+ INSERT_PADDING_BYTES_NOINIT(0x24);
+ I2M i2m; ///< 0x01DC
+ u32 run_ds_now; ///< 0x0200
+ OpportunisticEarlyZ opportunistic_early_z; ///< 0x0204
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 aliased_line_width_enabled; ///< 0x020C
+ u32 mandated_early_z; ///< 0x0210
+ GeometryShaderDmFifo gs_dm_fifo; ///< 0x0214
+ L2CacheControl l2_cache_control; ///< 0x0218
+ InvalidateShaderCache invalidate_shader_cache; ///< 0x021C
+ INSERT_PADDING_BYTES_NOINIT(0xA8);
+ SyncInfo sync_info; ///< 0x02C8
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 prim_circular_buffer_throttle; ///< 0x02D0
+ u32 flush_invalidate_rop_mini_cache; ///< 0x02D4
+ SurfaceClipBlockId surface_clip_block_id; ///< 0x02D8
+ u32 alpha_circular_buffer_size; ///< 0x02DC
+ DecompressSurface decompress_surface; ///< 0x02E0
+ ZCullRopBypass zcull_rop_bypass; ///< 0x02E4
+ ZCullSubregion zcull_subregion; ///< 0x02E8
+ RasterBoundingBox raster_bounding_box; ///< 0x02EC
+ u32 peer_semaphore_release; ///< 0x02F0
+ u32 iterated_blend_optimization; ///< 0x02F4
+ ZCullSubregionAllocation zcull_subregion_allocation; ///< 0x02F8
+ ZCullSubregionAlgorithm zcull_subregion_algorithm; ///< 0x02FC
+ PixelShaderOutputSampleMaskUsage ps_output_sample_mask_usage; ///< 0x0300
+ u32 draw_zero_index; ///< 0x0304
+ L1Configuration l1_configuration; ///< 0x0308
+ u32 render_enable_control_load_const_buffer; ///< 0x030C
+ SPAVersion spa_version; ///< 0x0310
+ u32 ieee_clean_update; ///< 0x0314
+ SnapGrid snap_grid; ///< 0x0318
+ Tessellation tessellation; ///< 0x0320
+ SubTilingPerf sub_tiling_perf; ///< 0x0360
+ ZCullSubregionReport zcull_subregion_report; ///< 0x036C
+ BalancedPrimitiveWorkload balanced_primitive_workload; ///< 0x0374
+ u32 max_patches_per_batch; ///< 0x0378
+ u32 rasterize_enable; ///< 0x037C
+ TransformFeedback transform_feedback; ///< 0x0380
+ u32 raster_input; ///< 0x0740
+ u32 transform_feedback_enabled; ///< 0x0744
+ u32 primitive_restart_topology_change_enable; ///< 0x0748
+ u32 alpha_fraction; ///< 0x074C
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ HybridAntiAliasControl hybrid_aa_control; ///< 0x0754
+ INSERT_PADDING_BYTES_NOINIT(0x24);
+ ShaderLocalMemory shader_local_memory; ///< 0x077C
+ u32 color_zero_bandwidth_clear; ///< 0x07A4
+ u32 z_zero_bandwidth_clear; ///< 0x07A8
+ u32 isbe_save_restore_program_offset; ///< 0x07AC
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ ZCullRegion zcull_region; ///< 0x07C0
+ ZetaReadOnly zeta_read_only; ///< 0x07F8
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ std::array<RenderTargetConfig, NumRenderTargets> rt; ///< 0x0800
+ std::array<ViewportTransform, NumViewports> viewport_transform; ///< 0x0A00
+ std::array<Viewport, NumViewports> viewports; ///< 0x0C00
+ std::array<Window, 8> windows; ///< 0x0D00
+ std::array<ClipIdExtent, 4> clip_id_extent; ///< 0x0D40
+ u32 max_geometry_instances_per_task; ///< 0x0D60
+ VisibleCallLimit visible_call_limit; ///< 0x0D64
+ StatisticsCounter statistics_count; ///< 0x0D68
+ ClearRect clear_rect; ///< 0x0D6C
+ VertexBuffer vertex_buffer; ///< 0x0D74
+ DepthMode depth_mode; ///< 0x0D7C
+ std::array<f32, 4> clear_color; ///< 0x0D80
+ f32 clear_depth; ///< 0x0D90
+ u32 shader_cache_icache_prefetch; ///< 0x0D94
+ u32 force_transition_to_beta; ///< 0x0D98
+ u32 reduce_colour_thresholds; ///< 0x0D9C
+ s32 clear_stencil; ///< 0x0DA0
+ InvalidateShaderCacheNoWFI invalidate_shader_cache_no_wfi; ///< 0x0DA4
+ ZCullSerialization zcull_serialization; ///< 0x0DA8
+ PolygonMode polygon_mode_front; ///< 0x0DAC
+ PolygonMode polygon_mode_back; ///< 0x0DB0
+ u32 polygon_smooth; ///< 0x0DB4
+ u32 zeta_mark_clean_ieee; ///< 0x0DB8
+ ZCullDirFormat zcull_dir_format; ///< 0x0DBC
+ u32 polygon_offset_point_enable; ///< 0x0DC0
+ u32 polygon_offset_line_enable; ///< 0x0DC4
+ u32 polygon_offset_fill_enable; ///< 0x0DC8
+ u32 patch_vertices; ///< 0x0DCC
+ IteratedBlend iterated_blend; ///< 0x0DD0
+ ZCullCriterion zcull_criteria; ///< 0x0DD8
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 fragment_barrier; ///< 0x0DE0
+ u32 sm_timeout; ///< 0x0DE4
+ u32 primitive_restart_array; ///< 0x0DE8
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ LoadIteratedBlend load_iterated_blend; ///< 0x0DF0
+ u32 window_offset_x; ///< 0x0DF8
+ u32 window_offset_y; ///< 0x0DFC
+ std::array<ScissorTest, NumViewports> scissor_test; ///< 0x0E00
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ u32 select_texture_headers; ///< 0x0F10
+ VPCPerf vpc_perf; ///< 0x0F14
+ u32 pm_local_trigger; ///< 0x0F18
+ u32 post_z_pixel_imask; ///< 0x0F1C
+ INSERT_PADDING_BYTES_NOINIT(0x20);
+ ConstantColorRendering const_color_rendering; ///< 0x0F40
+ s32 stencil_back_ref; ///< 0x0F54
+ u32 stencil_back_mask; ///< 0x0F58
+ u32 stencil_back_func_mask; ///< 0x0F5C
+ INSERT_PADDING_BYTES_NOINIT(0x24);
+ VertexStreamSubstitute vertex_stream_substitute; ///< 0x0F84
+ u32 line_mode_clip_generated_edge_do_not_draw; ///< 0x0F8C
+ u32 color_mask_common; ///< 0x0F90
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ VTGWarpWatermarks vtg_warp_watermarks; ///< 0x0F98
+ f32 depth_bounds[2]; ///< 0x0F9C
+ SampleMask::Target sample_mask_target; ///< 0x0FA4
+ u32 color_target_mrt_enable; ///< 0x0FAC
+ NonMultisampledZ non_multisampled_z; ///< 0x0FB0
+ TIRMode tir_mode; ///< 0x0FB4
+ AntiAliasRaster anti_alias_raster; ///< 0x0FB8
+ SampleMask::Pos sample_mask_pos; ///< 0x0FBC
+ SurfaceClipIDMemory surface_clip_id_memory; ///< 0x0FCC
+ TIRModulation tir_modulation; ///< 0x0FD4
+ u32 blend_control_allow_float_pixel_kills; ///< 0x0FDC
+ Zeta zeta; ///< 0x0FE0
+ SurfaceClip surface_clip; ///< 0x0FF4
+ u32 tiled_cache_treat_heavy_as_light; ///< 0x0FFC
+ L2CacheVAFRequests l2_cache_vaf; ///< 0x1000
+ ViewportMulticast viewport_multicast; ///< 0x1004
+ u32 tessellation_cut_height; ///< 0x1008
+ u32 max_gs_instances_per_task; ///< 0x100C
+ u32 max_gs_output_vertices_per_task; ///< 0x1010
+ u32 reserved_sw_method0; ///< 0x1014
+ u32 gs_output_cb_storage_multiplier; ///< 0x1018
+ u32 beta_cb_storage_constant; ///< 0x101C
+ u32 ti_output_cb_storage_multiplier; ///< 0x1020
+ u32 alpha_cb_storage_constraint; ///< 0x1024
+ u32 reserved_sw_method1; ///< 0x1028
+ u32 reserved_sw_method2; ///< 0x102C
+ std::array<TIRModulationCoeff, 5> tir_modulation_coeff; ///< 0x1030
+ std::array<u32, 15> spare_nop; ///< 0x1044
+ INSERT_PADDING_BYTES_NOINIT(0x30);
+ std::array<u32, 7> reserved_sw_method3_to_7; ///< 0x10B0
+ ReduceColorThreshold reduce_color_thresholds_unorm8; ///< 0x10CC
+ std::array<u32, 4> reserved_sw_method10_to_13; ///< 0x10D0
+ ReduceColorThreshold reduce_color_thresholds_unorm10; ///< 0x10E0
+ ReduceColorThreshold reduce_color_thresholds_unorm16; ///< 0x10E4
+ ReduceColorThreshold reduce_color_thresholds_fp11; ///< 0x10E8
+ ReduceColorThreshold reduce_color_thresholds_fp16; ///< 0x10EC
+ ReduceColorThreshold reduce_color_thresholds_srgb8; ///< 0x10F0
+ u32 unbind_all_constant_buffers; ///< 0x10F4
+ ClearControl clear_control; ///< 0x10F8
+ L2CacheRopNonInterlockedReads l2_cache_rop_non_interlocked_reads; ///< 0x10FC
+ u32 reserved_sw_method14; ///< 0x1100
+ u32 reserved_sw_method15; ///< 0x1104
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 no_operation_data_high; ///< 0x110C
+ u32 depth_bias_control; ///< 0x1110
+ u32 pm_trigger_end; ///< 0x1114
+ u32 vertex_id_base; ///< 0x1118
+ u32 stencil_compression_enabled; ///< 0x111C
+ VertexOutputAttributeSkipMasks vertex_output_attribute_skip_masks; ///< 0x1120
+ TIRControl tir_control; ///< 0x1130
+ u32 mutable_method_treat_mutable_as_heavy; ///< 0x1134
+ u32 post_ps_use_pre_ps_coverage; ///< 0x1138
+ FillViaTriangleMode fill_via_triangle_mode; ///< 0x113C
+ u32 blend_per_format_snorm8_unorm16_snorm16_enabled; ///< 0x1140
+ u32 flush_pending_writes_sm_gloal_store; ///< 0x1144
+ INSERT_PADDING_BYTES_NOINIT(0x18);
+ std::array<VertexAttribute, NumVertexAttributes> vertex_attrib_format; ///< 0x1160
+ std::array<MsaaSampleLocation, 4> multisample_sample_locations; ///< 0x11E0
+ u32 offset_render_target_index_by_viewport_index; ///< 0x11F0
+ u32 force_heavy_method_sync; ///< 0x11F4
+ MultisampleCoverageToColor multisample_coverage_to_color; ///< 0x11F8
+ DecompressZetaSurface decompress_zeta_surface; ///< 0x11FC
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ ZetaSparse zeta_sparse; ///< 0x1208
+ u32 invalidate_sampler_cache; ///< 0x120C
+ u32 invalidate_texture_header_cache; ///< 0x1210
+ VertexArray vertex_array_instance_first; ///< 0x1214
+ VertexArray vertex_array_instance_subsequent; ///< 0x1218
+ RtControl rt_control; ///< 0x121C
+ CompressionThresholdSamples compression_threshold_samples; ///< 0x1220
+ PixelShaderInterlockControl ps_interlock_control; ///< 0x1224
+ ZetaSize zeta_size; ///< 0x1228
+ SamplerBinding sampler_binding; ///< 0x1234
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 draw_auto_byte_count; ///< 0x123C
+ std::array<u32, 8> post_vtg_shader_attrib_skip_mask; ///< 0x1240
+ PsTicketDispenserValue ps_ticket_dispenser_value; ///< 0x1260
+ INSERT_PADDING_BYTES_NOINIT(0x1C);
+ u32 circular_buffer_size; ///< 0x1280
+ RegisterWatermarks vtg_register_watermarks; ///< 0x1284
+ InvalidateTextureDataCacheNoWfi invalidate_texture_cache_no_wfi; ///< 0x1288
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ L2CacheRopNonInterlockedReads l2_cache_rop_interlocked_reads; ///< 0x1290
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ u32 primitive_restart_topology_change_index; ///< 0x12A4
+ INSERT_PADDING_BYTES_NOINIT(0x20);
+ ZCullRegionEnable zcull_region_enable; ///< 0x12C8
+ u32 depth_test_enable; ///< 0x12CC
+ FillMode fill_mode; ///< 0x12D0
+ ShadeMode shade_mode; ///< 0x12D4
+ L2CacheRopNonInterlockedReads l2_cache_rop_non_interlocked_writes; ///< 0x12D8
+ L2CacheRopNonInterlockedReads l2_cache_rop_interlocked_writes; ///< 0x12DC
+ AlphaToCoverageDither alpha_to_coverage_dither; ///< 0x12E0
+ u32 blend_per_target_enabled; ///< 0x12E4
+ u32 depth_write_enabled; ///< 0x12E8
+ u32 alpha_test_enabled; ///< 0x12EC
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ InlineIndex4x8 inline_index_4x8; ///< 0x1300
+ D3DCullMode d3d_cull_mode; ///< 0x1308
+ ComparisonOp depth_test_func; ///< 0x130C
+ f32 alpha_test_ref; ///< 0x1310
+ ComparisonOp alpha_test_func; ///< 0x1314
+ u32 draw_auto_stride; ///< 0x1318
+ BlendColor blend_color; ///< 0x131C
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ InvalidateCacheLines invalidate_sampler_cache_lines; ///< 0x1330
+ InvalidateCacheLines invalidate_texture_header_cache_lines; ///< 0x1334
+ InvalidateCacheLines invalidate_texture_data_cache_lines; ///< 0x1338
+ Blend blend; ///< 0x133C
+ u32 stencil_enable; ///< 0x1380
+ StencilOp stencil_front_op; ///< 0x1384
+ s32 stencil_front_ref; ///< 0x1394
+ s32 stencil_front_func_mask; ///< 0x1398
+ s32 stencil_front_mask; ///< 0x139C
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 draw_auto_start_byte_count; ///< 0x13A4
+ PsSaturate frag_color_clamp; ///< 0x13A8
+ WindowOrigin window_origin; ///< 0x13AC
+ f32 line_width_smooth; ///< 0x13B0
+ f32 line_width_aliased; ///< 0x13B4
+ INSERT_PADDING_BYTES_NOINIT(0x60);
+ u32 line_override_multisample; ///< 0x1418
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 alpha_hysteresis_rounds; ///< 0x1420
+ InvalidateCacheLines invalidate_sampler_cache_no_wfi; ///< 0x1424
+ InvalidateCacheLines invalidate_texture_header_cache_no_wfi; ///< 0x1428
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ u32 global_base_vertex_index; ///< 0x1434
+ u32 global_base_instance_index; ///< 0x1438
+ INSERT_PADDING_BYTES_NOINIT(0x14);
+ RegisterWatermarks ps_warp_watermarks; ///< 0x1450
+ RegisterWatermarks ps_regster_watermarks; ///< 0x1454
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ u32 store_zcull; ///< 0x1464
+ INSERT_PADDING_BYTES_NOINIT(0x18);
+ std::array<IteratedBlendConstants, NumRenderTargets>
+ iterated_blend_constants; ///< 0x1480
+ u32 load_zcull; ///< 0x1500
+ u32 surface_clip_id_height; ///< 0x1504
+ Window surface_clip_id_clear_rect; ///< 0x1508
+ UserClip::Enable user_clip_enable; ///< 0x1510
+ u32 zpass_pixel_count_enable; ///< 0x1514
+ f32 point_size; ///< 0x1518
+ u32 zcull_stats_enable; ///< 0x151C
+ u32 point_sprite_enable; ///< 0x1520
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 shader_exceptions_enable; ///< 0x1528
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ ClearReport clear_report_value; ///< 0x1530
+ u32 anti_alias_enable; ///< 0x1534
+ u32 zeta_enable; ///< 0x1538
+ AntiAliasAlphaControl anti_alias_alpha_control; ///< 0x153C
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ RenderEnable render_enable; ///< 0x1550
+ TexSampler tex_sampler; ///< 0x155C
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ f32 slope_scale_depth_bias; ///< 0x156C
+ u32 line_anti_alias_enable; ///< 0x1570
+ TexHeader tex_header; ///< 0x1574
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ u32 active_zcull_region_id; ///< 0x1590
+ u32 stencil_two_side_enable; ///< 0x1594
+ StencilOp stencil_back_op; ///< 0x1598
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ u32 framebuffer_srgb; ///< 0x15B8
+ f32 depth_bias; ///< 0x15BC
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ ZCullRegionFormat zcull_region_format; ///< 0x15C8
+ RtLayer rt_layer; ///< 0x15CC
+ Tegra::Texture::MsaaMode anti_alias_samples_mode; ///< 0x15D0
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ u32 edge_flag; ///< 0x15E4
+ u32 draw_inline_index; ///< 0x15E8
+ InlineIndex2x16 inline_index_2x16; ///< 0x15EC
+ VertexGlobalBaseOffset vertex_global_base_offset; ///< 0x15F4
+ ZCullRegionPixelOffset zcull_region_pixel_offset; ///< 0x15FC
+ PointSprite point_sprite; ///< 0x1604
+ ProgramRegion program_region; ///< 0x1608
+ DefaultAttributes default_attributes; ///< 0x1610
+ Draw draw; ///< 0x1614
+ VertexIdCopy vertex_id_copy; ///< 0x161C
+ u32 add_to_primitive_id; ///< 0x1620
+ u32 load_to_primitive_id; ///< 0x1624
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ ShaderBasedCull shader_based_cull; ///< 0x162C
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ ClassVersion class_version; ///< 0x1638
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ PrimitiveRestart primitive_restart; ///< 0x1644
+ OutputVertexId output_vertex_id; ///< 0x164C
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ u32 anti_alias_point_enable; ///< 0x1658
+ PointCenterMode point_center_mode; ///< 0x165C
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ LineSmoothParams line_smooth_params; ///< 0x1668
+ u32 line_stipple_enable; ///< 0x166C
+ std::array<LineSmoothEdgeTable, 4> line_smooth_edge_table; ///< 0x1670
+ LineStippleParams line_stipple_params; ///< 0x1680
+ ProvokingVertex provoking_vertex; ///< 0x1684
+ u32 two_sided_light_enabled; ///< 0x1688
+ u32 polygon_stipple_enabled; ///< 0x168C
+ ShaderControl shader_control; ///< 0x1690
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ ClassVersion class_version_check; ///< 0x16A0
+ SphVersion sph_version; ///< 0x16A4
+ SphVersion sph_version_check; ///< 0x16A8
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ AlphaToCoverageOverride alpha_to_coverage_override; ///< 0x16B4
+ INSERT_PADDING_BYTES_NOINIT(0x48);
+ std::array<u32, 32> polygon_stipple_pattern; ///< 0x1700
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ AamVersion aam_version; ///< 0x1790
+ AamVersion aam_version_check; ///< 0x1794
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 zeta_layer_offset; ///< 0x179C
+ INSERT_PADDING_BYTES_NOINIT(0x28);
+ IndexBuffer index_buffer; ///< 0x17C8
+ IndexBufferSmall index_buffer32_first; ///< 0x17E4
+ IndexBufferSmall index_buffer16_first; ///< 0x17E8
+ IndexBufferSmall index_buffer8_first; ///< 0x17EC
+ IndexBufferSmall index_buffer32_subsequent; ///< 0x17F0
+ IndexBufferSmall index_buffer16_subsequent; ///< 0x17F4
+ IndexBufferSmall index_buffer8_subsequent; ///< 0x17F8
+ INSERT_PADDING_BYTES_NOINIT(0x80);
+ f32 depth_bias_clamp; ///< 0x187C
+ VertexStreamInstances vertex_stream_instances; ///< 0x1880
+ INSERT_PADDING_BYTES_NOINIT(0x10);
+ AttributePointSize point_size_attribute; ///< 0x1910
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 gl_cull_test_enabled; ///< 0x1918
+ FrontFace gl_front_face; ///< 0x191C
+ CullFace gl_cull_face; ///< 0x1920
+ Viewport::PixelCenter viewport_pixel_center; ///< 0x1924
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 viewport_scale_offset_enbled; ///< 0x192C
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ ViewportClipControl viewport_clip_control; ///< 0x193C
+ UserClip::Op user_clip_op; ///< 0x1940
+ RenderEnable::Override render_enable_override; ///< 0x1944
+ PrimitiveTopologyControl primitive_topology_control; ///< 0x1948
+ WindowClip window_clip_enable; ///< 0x194C
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ InvalidateZCull invalidate_zcull; ///< 0x1958
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ ZCull zcull; ///< 0x1968
+ PrimitiveTopologyOverride topology_override; ///< 0x1970
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 zcull_sync; ///< 0x1978
+ u32 clip_id_test_enable; ///< 0x197C
+ u32 surface_clip_id_width; ///< 0x1980
+ u32 clip_id; ///< 0x1984
+ INSERT_PADDING_BYTES_NOINIT(0x34);
+ u32 depth_bounds_enable; ///< 0x19BC
+ u32 blend_float_zero_times_anything_is_zero; ///< 0x19C0
+ LogicOp logic_op; ///< 0x19C4
+ u32 z_compression_enable; ///< 0x19CC
+ ClearSurface clear_surface; ///< 0x19D0
+ u32 clear_clip_id_surface; ///< 0x19D4
+ INSERT_PADDING_BYTES_NOINIT(0x8);
+ std::array<u32, NumRenderTargets> color_compression_enable; ///< 0x19E0
+ std::array<ColorMask, NumRenderTargets> color_mask; ///< 0x1A00
+ INSERT_PADDING_BYTES_NOINIT(0xC);
+ u32 pipe_nop; ///< 0x1A2C
+ std::array<u32, 4> spare; ///< 0x1A30
+ INSERT_PADDING_BYTES_NOINIT(0xC0);
+ ReportSemaphore report_semaphore; ///< 0x1B00
+ INSERT_PADDING_BYTES_NOINIT(0xF0);
+ std::array<VertexStream, NumVertexArrays> vertex_streams; ///< 0x1C00
+ BlendPerTarget blend_per_target[NumRenderTargets]; ///< 0x1E00
+ std::array<VertexStreamLimit, NumVertexArrays> vertex_stream_limits; ///< 0x1F00
+ std::array<Pipeline, MaxShaderProgram> pipelines; ///< 0x2000
+ INSERT_PADDING_BYTES_NOINIT(0x180);
+ u32 falcon[32]; ///< 0x2300
+ ConstantBuffer const_buffer; ///< 0x2380
+ INSERT_PADDING_BYTES_NOINIT(0x30);
+ BindGroup bind_groups[MaxShaderStage]; ///< 0x2400
+ INSERT_PADDING_BYTES_NOINIT(0x160);
+ u32 color_clamp_enable; ///< 0x2600
+ INSERT_PADDING_BYTES_NOINIT(0x4);
+ u32 bindless_texture_const_buffer_slot; ///< 0x2608
+ u32 trap_handler; ///< 0x260C
+ INSERT_PADDING_BYTES_NOINIT(0x1F0);
+ std::array<std::array<StreamOutLayout, 32>, NumTransformFeedbackBuffers>
+ stream_out_layout; ///< 0x2800
+ INSERT_PADDING_BYTES_NOINIT(0x93C);
+ ShaderPerformance shader_performance; ///< 0x333C
+ INSERT_PADDING_BYTES_NOINIT(0x18);
+ std::array<u32, 0x100> shadow_scratch; ///< 0x3400
};
std::array<u32, NUM_REGS> reg_array;
};
};
+ // clang-format on
Regs regs{};
@@ -1438,8 +3044,6 @@ public:
};
std::array<ShaderStageInfo, Regs::MaxShaderStage> shader_stages;
-
- u32 current_instance = 0; ///< Current instance to be used to simulate instanced rendering.
};
State state{};
@@ -1454,11 +3058,6 @@ public:
void CallMultiMethod(u32 method, const u32* base_start, u32 amount,
u32 methods_pending) override;
- /// Write the value to the register identified by method.
- void CallMethodFromMME(u32 method, u32 method_argument);
-
- void FlushMMEInlineDraw();
-
bool ShouldExecute() const {
return execute_on;
}
@@ -1471,21 +3070,6 @@ public:
return *rasterizer;
}
- enum class MMEDrawMode : u32 {
- Undefined,
- Array,
- Indexed,
- };
-
- struct MMEDrawState {
- MMEDrawMode current_mode{MMEDrawMode::Undefined};
- u32 current_count{};
- u32 instance_count{};
- bool instance_mode{};
- bool gl_begin_consume{};
- u32 gl_end_count{};
- } mme_draw;
-
struct DirtyState {
using Flags = std::bitset<std::numeric_limits<u8>::max()>;
using Table = std::array<u8, Regs::NUM_REGS>;
@@ -1495,6 +3079,8 @@ public:
Tables tables{};
} dirty;
+ std::vector<u8> inline_index_draw_indexes;
+
private:
void InitializeRegisterDefaults();
@@ -1554,14 +3140,12 @@ private:
/// Handles a write to the CB_BIND register.
void ProcessCBBind(size_t stage_index);
- /// Handles a write to the VERTEX_END_GL register, triggering a draw.
- void DrawArrays();
-
/// Handles use of topology overrides (e.g., to avoid using a topology assigned from a macro)
void ProcessTopologyOverride();
- // Handles a instance drawcall from MME
- void StepInstance(MMEDrawMode expected_mode, u32 count);
+ void ProcessDraw(u32 instance_count = 1);
+
+ void ProcessDeferredDraw();
/// Returns a query's value or an empty object if the value will be deferred through a cache.
std::optional<u64> GetQueryResult();
@@ -1574,8 +3158,6 @@ private:
/// Start offsets of each macro in macro_memory
std::array<u32, 0x80> macro_positions{};
- std::array<bool, Regs::NUM_REGS> mme_inline{};
-
/// Macro method that is currently being executed / being fed parameters.
u32 executing_macro = 0;
/// Parameters that have been submitted to the macro call so far.
@@ -1588,150 +3170,355 @@ private:
bool execute_on{true};
bool use_topology_override{false};
+
+ std::array<bool, Regs::NUM_REGS> draw_command{};
+ std::vector<u32> deferred_draw_method;
};
#define ASSERT_REG_POSITION(field_name, position) \
- static_assert(offsetof(Maxwell3D::Regs, field_name) == position * 4, \
+ static_assert(offsetof(Maxwell3D::Regs, field_name) == position, \
"Field " #field_name " has invalid position")
-ASSERT_REG_POSITION(wait_for_idle, 0x44);
-ASSERT_REG_POSITION(macros, 0x45);
-ASSERT_REG_POSITION(shadow_ram_control, 0x49);
-ASSERT_REG_POSITION(upload, 0x60);
-ASSERT_REG_POSITION(exec_upload, 0x6C);
-ASSERT_REG_POSITION(data_upload, 0x6D);
-ASSERT_REG_POSITION(force_early_fragment_tests, 0x84);
-ASSERT_REG_POSITION(sync_info, 0xB2);
-ASSERT_REG_POSITION(tess_mode, 0xC8);
-ASSERT_REG_POSITION(tess_level_outer, 0xC9);
-ASSERT_REG_POSITION(tess_level_inner, 0xCD);
-ASSERT_REG_POSITION(rasterize_enable, 0xDF);
-ASSERT_REG_POSITION(tfb_bindings, 0xE0);
-ASSERT_REG_POSITION(tfb_layouts, 0x1C0);
-ASSERT_REG_POSITION(tfb_enabled, 0x1D1);
-ASSERT_REG_POSITION(rt, 0x200);
-ASSERT_REG_POSITION(viewport_transform, 0x280);
-ASSERT_REG_POSITION(viewports, 0x300);
-ASSERT_REG_POSITION(vertex_buffer, 0x35D);
-ASSERT_REG_POSITION(depth_mode, 0x35F);
-ASSERT_REG_POSITION(clear_color[0], 0x360);
-ASSERT_REG_POSITION(clear_depth, 0x364);
-ASSERT_REG_POSITION(clear_stencil, 0x368);
-ASSERT_REG_POSITION(polygon_mode_front, 0x36B);
-ASSERT_REG_POSITION(polygon_mode_back, 0x36C);
-ASSERT_REG_POSITION(polygon_offset_point_enable, 0x370);
-ASSERT_REG_POSITION(polygon_offset_line_enable, 0x371);
-ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x372);
-ASSERT_REG_POSITION(patch_vertices, 0x373);
-ASSERT_REG_POSITION(fragment_barrier, 0x378);
-ASSERT_REG_POSITION(scissor_test, 0x380);
-ASSERT_REG_POSITION(stencil_back_func_ref, 0x3D5);
-ASSERT_REG_POSITION(stencil_back_mask, 0x3D6);
-ASSERT_REG_POSITION(stencil_back_func_mask, 0x3D7);
-ASSERT_REG_POSITION(invalidate_texture_data_cache, 0x3DD);
-ASSERT_REG_POSITION(tiled_cache_barrier, 0x3DF);
-ASSERT_REG_POSITION(color_mask_common, 0x3E4);
-ASSERT_REG_POSITION(depth_bounds, 0x3E7);
-ASSERT_REG_POSITION(rt_separate_frag_data, 0x3EB);
-ASSERT_REG_POSITION(multisample_raster_enable, 0x3ED);
-ASSERT_REG_POSITION(multisample_raster_samples, 0x3EE);
-ASSERT_REG_POSITION(multisample_sample_mask, 0x3EF);
-ASSERT_REG_POSITION(zeta, 0x3F8);
-ASSERT_REG_POSITION(render_area, 0x3FD);
-ASSERT_REG_POSITION(clear_flags, 0x43E);
-ASSERT_REG_POSITION(fill_rectangle, 0x44F);
-ASSERT_REG_POSITION(conservative_raster_enable, 0x452);
-ASSERT_REG_POSITION(vertex_attrib_format, 0x458);
-ASSERT_REG_POSITION(multisample_sample_locations, 0x478);
-ASSERT_REG_POSITION(multisample_coverage_to_color, 0x47E);
-ASSERT_REG_POSITION(rt_control, 0x487);
-ASSERT_REG_POSITION(zeta_width, 0x48a);
-ASSERT_REG_POSITION(zeta_height, 0x48b);
-ASSERT_REG_POSITION(zeta_depth, 0x48c);
-ASSERT_REG_POSITION(sampler_index, 0x48D);
-ASSERT_REG_POSITION(gp_passthrough_mask, 0x490);
-ASSERT_REG_POSITION(depth_test_enable, 0x4B3);
-ASSERT_REG_POSITION(independent_blend_enable, 0x4B9);
-ASSERT_REG_POSITION(depth_write_enabled, 0x4BA);
-ASSERT_REG_POSITION(alpha_test_enabled, 0x4BB);
-ASSERT_REG_POSITION(d3d_cull_mode, 0x4C2);
-ASSERT_REG_POSITION(depth_test_func, 0x4C3);
-ASSERT_REG_POSITION(alpha_test_ref, 0x4C4);
-ASSERT_REG_POSITION(alpha_test_func, 0x4C5);
-ASSERT_REG_POSITION(draw_tfb_stride, 0x4C6);
-ASSERT_REG_POSITION(blend_color, 0x4C7);
-ASSERT_REG_POSITION(blend, 0x4CF);
-ASSERT_REG_POSITION(stencil_enable, 0x4E0);
-ASSERT_REG_POSITION(stencil_front_op_fail, 0x4E1);
-ASSERT_REG_POSITION(stencil_front_op_zfail, 0x4E2);
-ASSERT_REG_POSITION(stencil_front_op_zpass, 0x4E3);
-ASSERT_REG_POSITION(stencil_front_func_func, 0x4E4);
-ASSERT_REG_POSITION(stencil_front_func_ref, 0x4E5);
-ASSERT_REG_POSITION(stencil_front_func_mask, 0x4E6);
-ASSERT_REG_POSITION(stencil_front_mask, 0x4E7);
-ASSERT_REG_POSITION(frag_color_clamp, 0x4EA);
-ASSERT_REG_POSITION(screen_y_control, 0x4EB);
-ASSERT_REG_POSITION(line_width_smooth, 0x4EC);
-ASSERT_REG_POSITION(line_width_aliased, 0x4ED);
-ASSERT_REG_POSITION(invalidate_sampler_cache_no_wfi, 0x509);
-ASSERT_REG_POSITION(invalidate_texture_header_cache_no_wfi, 0x50A);
-ASSERT_REG_POSITION(vb_element_base, 0x50D);
-ASSERT_REG_POSITION(vb_base_instance, 0x50E);
-ASSERT_REG_POSITION(clip_distance_enabled, 0x544);
-ASSERT_REG_POSITION(samplecnt_enable, 0x545);
-ASSERT_REG_POSITION(point_size, 0x546);
-ASSERT_REG_POSITION(point_sprite_enable, 0x548);
-ASSERT_REG_POSITION(counter_reset, 0x54C);
-ASSERT_REG_POSITION(multisample_enable, 0x54D);
-ASSERT_REG_POSITION(zeta_enable, 0x54E);
-ASSERT_REG_POSITION(multisample_control, 0x54F);
-ASSERT_REG_POSITION(condition, 0x554);
-ASSERT_REG_POSITION(tsc, 0x557);
-ASSERT_REG_POSITION(polygon_offset_factor, 0x55B);
-ASSERT_REG_POSITION(line_smooth_enable, 0x55C);
-ASSERT_REG_POSITION(tic, 0x55D);
-ASSERT_REG_POSITION(stencil_two_side_enable, 0x565);
-ASSERT_REG_POSITION(stencil_back_op_fail, 0x566);
-ASSERT_REG_POSITION(stencil_back_op_zfail, 0x567);
-ASSERT_REG_POSITION(stencil_back_op_zpass, 0x568);
-ASSERT_REG_POSITION(stencil_back_func_func, 0x569);
-ASSERT_REG_POSITION(framebuffer_srgb, 0x56E);
-ASSERT_REG_POSITION(polygon_offset_units, 0x56F);
-ASSERT_REG_POSITION(multisample_mode, 0x574);
-ASSERT_REG_POSITION(point_coord_replace, 0x581);
-ASSERT_REG_POSITION(code_address, 0x582);
-ASSERT_REG_POSITION(draw, 0x585);
-ASSERT_REG_POSITION(primitive_restart, 0x591);
-ASSERT_REG_POSITION(provoking_vertex_last, 0x5A1);
-ASSERT_REG_POSITION(index_array, 0x5F2);
-ASSERT_REG_POSITION(small_index, 0x5F9);
-ASSERT_REG_POSITION(polygon_offset_clamp, 0x61F);
-ASSERT_REG_POSITION(instanced_arrays, 0x620);
-ASSERT_REG_POSITION(vp_point_size, 0x644);
-ASSERT_REG_POSITION(cull_test_enabled, 0x646);
-ASSERT_REG_POSITION(front_face, 0x647);
-ASSERT_REG_POSITION(cull_face, 0x648);
-ASSERT_REG_POSITION(pixel_center_integer, 0x649);
-ASSERT_REG_POSITION(viewport_transform_enabled, 0x64B);
-ASSERT_REG_POSITION(view_volume_clip_control, 0x64F);
-ASSERT_REG_POSITION(topology_override, 0x65C);
-ASSERT_REG_POSITION(depth_bounds_enable, 0x66F);
-ASSERT_REG_POSITION(logic_op, 0x671);
-ASSERT_REG_POSITION(clear_buffers, 0x674);
-ASSERT_REG_POSITION(color_mask, 0x680);
-ASSERT_REG_POSITION(query, 0x6C0);
-ASSERT_REG_POSITION(vertex_array[0], 0x700);
-ASSERT_REG_POSITION(independent_blend, 0x780);
-ASSERT_REG_POSITION(vertex_array_limit[0], 0x7C0);
-ASSERT_REG_POSITION(shader_config[0], 0x800);
-ASSERT_REG_POSITION(firmware, 0x8C0);
-ASSERT_REG_POSITION(const_buffer, 0x8E0);
-ASSERT_REG_POSITION(cb_bind[0], 0x904);
-ASSERT_REG_POSITION(tex_cb_index, 0x982);
-ASSERT_REG_POSITION(tfb_varying_locs, 0xA00);
-ASSERT_REG_POSITION(ssbo_info, 0xD18);
-ASSERT_REG_POSITION(tex_info_buffers.address[0], 0xD2A);
-ASSERT_REG_POSITION(tex_info_buffers.size[0], 0xD2F);
+ASSERT_REG_POSITION(object_id, 0x0000);
+ASSERT_REG_POSITION(nop, 0x0100);
+ASSERT_REG_POSITION(notify, 0x0104);
+ASSERT_REG_POSITION(wait_for_idle, 0x0110);
+ASSERT_REG_POSITION(load_mme, 0x0114);
+ASSERT_REG_POSITION(shadow_ram_control, 0x0124);
+ASSERT_REG_POSITION(peer, 0x0128);
+ASSERT_REG_POSITION(global_render, 0x0130);
+ASSERT_REG_POSITION(go_idle, 0x013C);
+ASSERT_REG_POSITION(trigger, 0x0140);
+ASSERT_REG_POSITION(trigger_wfi, 0x0144);
+ASSERT_REG_POSITION(instrumentation_method_header, 0x0150);
+ASSERT_REG_POSITION(instrumentation_method_data, 0x0154);
+ASSERT_REG_POSITION(upload, 0x0180);
+ASSERT_REG_POSITION(launch_dma, 0x01B0);
+ASSERT_REG_POSITION(inline_data, 0x01B4);
+ASSERT_REG_POSITION(i2m, 0x01DC);
+ASSERT_REG_POSITION(run_ds_now, 0x0200);
+ASSERT_REG_POSITION(opportunistic_early_z, 0x0204);
+ASSERT_REG_POSITION(aliased_line_width_enabled, 0x020C);
+ASSERT_REG_POSITION(mandated_early_z, 0x0210);
+ASSERT_REG_POSITION(gs_dm_fifo, 0x0214);
+ASSERT_REG_POSITION(l2_cache_control, 0x0218);
+ASSERT_REG_POSITION(invalidate_shader_cache, 0x021C);
+ASSERT_REG_POSITION(sync_info, 0x02C8);
+ASSERT_REG_POSITION(prim_circular_buffer_throttle, 0x02D0);
+ASSERT_REG_POSITION(flush_invalidate_rop_mini_cache, 0x02D4);
+ASSERT_REG_POSITION(surface_clip_block_id, 0x02D8);
+ASSERT_REG_POSITION(alpha_circular_buffer_size, 0x02DC);
+ASSERT_REG_POSITION(decompress_surface, 0x02E0);
+ASSERT_REG_POSITION(zcull_rop_bypass, 0x02E4);
+ASSERT_REG_POSITION(zcull_subregion, 0x02E8);
+ASSERT_REG_POSITION(raster_bounding_box, 0x02EC);
+ASSERT_REG_POSITION(peer_semaphore_release, 0x02F0);
+ASSERT_REG_POSITION(iterated_blend_optimization, 0x02F4);
+ASSERT_REG_POSITION(zcull_subregion_allocation, 0x02F8);
+ASSERT_REG_POSITION(zcull_subregion_algorithm, 0x02FC);
+ASSERT_REG_POSITION(ps_output_sample_mask_usage, 0x0300);
+ASSERT_REG_POSITION(draw_zero_index, 0x0304);
+ASSERT_REG_POSITION(l1_configuration, 0x0308);
+ASSERT_REG_POSITION(render_enable_control_load_const_buffer, 0x030C);
+ASSERT_REG_POSITION(spa_version, 0x0310);
+ASSERT_REG_POSITION(ieee_clean_update, 0x0314);
+ASSERT_REG_POSITION(snap_grid, 0x0318);
+ASSERT_REG_POSITION(tessellation, 0x0320);
+ASSERT_REG_POSITION(sub_tiling_perf, 0x0360);
+ASSERT_REG_POSITION(zcull_subregion_report, 0x036C);
+ASSERT_REG_POSITION(balanced_primitive_workload, 0x0374);
+ASSERT_REG_POSITION(max_patches_per_batch, 0x0378);
+ASSERT_REG_POSITION(rasterize_enable, 0x037C);
+ASSERT_REG_POSITION(transform_feedback, 0x0380);
+ASSERT_REG_POSITION(transform_feedback.controls, 0x0700);
+ASSERT_REG_POSITION(raster_input, 0x0740);
+ASSERT_REG_POSITION(transform_feedback_enabled, 0x0744);
+ASSERT_REG_POSITION(primitive_restart_topology_change_enable, 0x0748);
+ASSERT_REG_POSITION(alpha_fraction, 0x074C);
+ASSERT_REG_POSITION(hybrid_aa_control, 0x0754);
+ASSERT_REG_POSITION(shader_local_memory, 0x077C);
+ASSERT_REG_POSITION(color_zero_bandwidth_clear, 0x07A4);
+ASSERT_REG_POSITION(z_zero_bandwidth_clear, 0x07A8);
+ASSERT_REG_POSITION(isbe_save_restore_program_offset, 0x07AC);
+ASSERT_REG_POSITION(zcull_region, 0x07C0);
+ASSERT_REG_POSITION(zeta_read_only, 0x07F8);
+ASSERT_REG_POSITION(rt, 0x0800);
+ASSERT_REG_POSITION(viewport_transform, 0x0A00);
+ASSERT_REG_POSITION(viewports, 0x0C00);
+ASSERT_REG_POSITION(windows, 0x0D00);
+ASSERT_REG_POSITION(clip_id_extent, 0x0D40);
+ASSERT_REG_POSITION(max_geometry_instances_per_task, 0x0D60);
+ASSERT_REG_POSITION(visible_call_limit, 0x0D64);
+ASSERT_REG_POSITION(statistics_count, 0x0D68);
+ASSERT_REG_POSITION(clear_rect, 0x0D6C);
+ASSERT_REG_POSITION(vertex_buffer, 0x0D74);
+ASSERT_REG_POSITION(depth_mode, 0x0D7C);
+ASSERT_REG_POSITION(clear_color, 0x0D80);
+ASSERT_REG_POSITION(clear_depth, 0x0D90);
+ASSERT_REG_POSITION(shader_cache_icache_prefetch, 0x0D94);
+ASSERT_REG_POSITION(force_transition_to_beta, 0x0D98);
+ASSERT_REG_POSITION(reduce_colour_thresholds, 0x0D9C);
+ASSERT_REG_POSITION(clear_stencil, 0x0DA0);
+ASSERT_REG_POSITION(invalidate_shader_cache_no_wfi, 0x0DA4);
+ASSERT_REG_POSITION(zcull_serialization, 0x0DA8);
+ASSERT_REG_POSITION(polygon_mode_front, 0x0DAC);
+ASSERT_REG_POSITION(polygon_mode_back, 0x0DB0);
+ASSERT_REG_POSITION(polygon_smooth, 0x0DB4);
+ASSERT_REG_POSITION(zeta_mark_clean_ieee, 0x0DB8);
+ASSERT_REG_POSITION(zcull_dir_format, 0x0DBC);
+ASSERT_REG_POSITION(polygon_offset_point_enable, 0x0DC0);
+ASSERT_REG_POSITION(polygon_offset_line_enable, 0x0DC4);
+ASSERT_REG_POSITION(polygon_offset_fill_enable, 0x0DC8);
+ASSERT_REG_POSITION(patch_vertices, 0x0DCC);
+ASSERT_REG_POSITION(iterated_blend, 0x0DD0);
+ASSERT_REG_POSITION(zcull_criteria, 0x0DD8);
+ASSERT_REG_POSITION(fragment_barrier, 0x0DE0);
+ASSERT_REG_POSITION(sm_timeout, 0x0DE4);
+ASSERT_REG_POSITION(primitive_restart_array, 0x0DE8);
+ASSERT_REG_POSITION(load_iterated_blend, 0x0DF0);
+ASSERT_REG_POSITION(window_offset_x, 0x0DF8);
+ASSERT_REG_POSITION(window_offset_y, 0x0DFC);
+ASSERT_REG_POSITION(scissor_test, 0x0E00);
+ASSERT_REG_POSITION(select_texture_headers, 0x0F10);
+ASSERT_REG_POSITION(vpc_perf, 0x0F14);
+ASSERT_REG_POSITION(pm_local_trigger, 0x0F18);
+ASSERT_REG_POSITION(post_z_pixel_imask, 0x0F1C);
+ASSERT_REG_POSITION(const_color_rendering, 0x0F40);
+ASSERT_REG_POSITION(stencil_back_ref, 0x0F54);
+ASSERT_REG_POSITION(stencil_back_mask, 0x0F58);
+ASSERT_REG_POSITION(stencil_back_func_mask, 0x0F5C);
+ASSERT_REG_POSITION(vertex_stream_substitute, 0x0F84);
+ASSERT_REG_POSITION(line_mode_clip_generated_edge_do_not_draw, 0x0F8C);
+ASSERT_REG_POSITION(color_mask_common, 0x0F90);
+ASSERT_REG_POSITION(vtg_warp_watermarks, 0x0F98);
+ASSERT_REG_POSITION(depth_bounds, 0x0F9C);
+ASSERT_REG_POSITION(sample_mask_target, 0x0FA4);
+ASSERT_REG_POSITION(color_target_mrt_enable, 0x0FAC);
+ASSERT_REG_POSITION(non_multisampled_z, 0x0FB0);
+ASSERT_REG_POSITION(tir_mode, 0x0FB4);
+ASSERT_REG_POSITION(anti_alias_raster, 0x0FB8);
+ASSERT_REG_POSITION(sample_mask_pos, 0x0FBC);
+ASSERT_REG_POSITION(surface_clip_id_memory, 0x0FCC);
+ASSERT_REG_POSITION(tir_modulation, 0x0FD4);
+ASSERT_REG_POSITION(blend_control_allow_float_pixel_kills, 0x0FDC);
+ASSERT_REG_POSITION(zeta, 0x0FE0);
+ASSERT_REG_POSITION(surface_clip, 0x0FF4);
+ASSERT_REG_POSITION(tiled_cache_treat_heavy_as_light, 0x0FFC);
+ASSERT_REG_POSITION(l2_cache_vaf, 0x1000);
+ASSERT_REG_POSITION(viewport_multicast, 0x1004);
+ASSERT_REG_POSITION(tessellation_cut_height, 0x1008);
+ASSERT_REG_POSITION(max_gs_instances_per_task, 0x100C);
+ASSERT_REG_POSITION(max_gs_output_vertices_per_task, 0x1010);
+ASSERT_REG_POSITION(reserved_sw_method0, 0x1014);
+ASSERT_REG_POSITION(gs_output_cb_storage_multiplier, 0x1018);
+ASSERT_REG_POSITION(beta_cb_storage_constant, 0x101C);
+ASSERT_REG_POSITION(ti_output_cb_storage_multiplier, 0x1020);
+ASSERT_REG_POSITION(alpha_cb_storage_constraint, 0x1024);
+ASSERT_REG_POSITION(reserved_sw_method1, 0x1028);
+ASSERT_REG_POSITION(reserved_sw_method2, 0x102C);
+ASSERT_REG_POSITION(tir_modulation_coeff, 0x1030);
+ASSERT_REG_POSITION(spare_nop, 0x1044);
+ASSERT_REG_POSITION(reserved_sw_method3_to_7, 0x10B0);
+ASSERT_REG_POSITION(reduce_color_thresholds_unorm8, 0x10CC);
+ASSERT_REG_POSITION(reserved_sw_method10_to_13, 0x10D0);
+ASSERT_REG_POSITION(reduce_color_thresholds_unorm10, 0x10E0);
+ASSERT_REG_POSITION(reduce_color_thresholds_unorm16, 0x10E4);
+ASSERT_REG_POSITION(reduce_color_thresholds_fp11, 0x10E8);
+ASSERT_REG_POSITION(reduce_color_thresholds_fp16, 0x10EC);
+ASSERT_REG_POSITION(reduce_color_thresholds_srgb8, 0x10F0);
+ASSERT_REG_POSITION(unbind_all_constant_buffers, 0x10F4);
+ASSERT_REG_POSITION(clear_control, 0x10F8);
+ASSERT_REG_POSITION(l2_cache_rop_non_interlocked_reads, 0x10FC);
+ASSERT_REG_POSITION(reserved_sw_method14, 0x1100);
+ASSERT_REG_POSITION(reserved_sw_method15, 0x1104);
+ASSERT_REG_POSITION(no_operation_data_high, 0x110C);
+ASSERT_REG_POSITION(depth_bias_control, 0x1110);
+ASSERT_REG_POSITION(pm_trigger_end, 0x1114);
+ASSERT_REG_POSITION(vertex_id_base, 0x1118);
+ASSERT_REG_POSITION(stencil_compression_enabled, 0x111C);
+ASSERT_REG_POSITION(vertex_output_attribute_skip_masks, 0x1120);
+ASSERT_REG_POSITION(tir_control, 0x1130);
+ASSERT_REG_POSITION(mutable_method_treat_mutable_as_heavy, 0x1134);
+ASSERT_REG_POSITION(post_ps_use_pre_ps_coverage, 0x1138);
+ASSERT_REG_POSITION(fill_via_triangle_mode, 0x113C);
+ASSERT_REG_POSITION(blend_per_format_snorm8_unorm16_snorm16_enabled, 0x1140);
+ASSERT_REG_POSITION(flush_pending_writes_sm_gloal_store, 0x1144);
+ASSERT_REG_POSITION(vertex_attrib_format, 0x1160);
+ASSERT_REG_POSITION(multisample_sample_locations, 0x11E0);
+ASSERT_REG_POSITION(offset_render_target_index_by_viewport_index, 0x11F0);
+ASSERT_REG_POSITION(force_heavy_method_sync, 0x11F4);
+ASSERT_REG_POSITION(multisample_coverage_to_color, 0x11F8);
+ASSERT_REG_POSITION(decompress_zeta_surface, 0x11FC);
+ASSERT_REG_POSITION(zeta_sparse, 0x1208);
+ASSERT_REG_POSITION(invalidate_sampler_cache, 0x120C);
+ASSERT_REG_POSITION(invalidate_texture_header_cache, 0x1210);
+ASSERT_REG_POSITION(vertex_array_instance_first, 0x1214);
+ASSERT_REG_POSITION(vertex_array_instance_subsequent, 0x1218);
+ASSERT_REG_POSITION(rt_control, 0x121C);
+ASSERT_REG_POSITION(compression_threshold_samples, 0x1220);
+ASSERT_REG_POSITION(ps_interlock_control, 0x1224);
+ASSERT_REG_POSITION(zeta_size, 0x1228);
+ASSERT_REG_POSITION(sampler_binding, 0x1234);
+ASSERT_REG_POSITION(draw_auto_byte_count, 0x123C);
+ASSERT_REG_POSITION(post_vtg_shader_attrib_skip_mask, 0x1240);
+ASSERT_REG_POSITION(ps_ticket_dispenser_value, 0x1260);
+ASSERT_REG_POSITION(circular_buffer_size, 0x1280);
+ASSERT_REG_POSITION(vtg_register_watermarks, 0x1284);
+ASSERT_REG_POSITION(invalidate_texture_cache_no_wfi, 0x1288);
+ASSERT_REG_POSITION(l2_cache_rop_interlocked_reads, 0x1290);
+ASSERT_REG_POSITION(primitive_restart_topology_change_index, 0x12A4);
+ASSERT_REG_POSITION(zcull_region_enable, 0x12C8);
+ASSERT_REG_POSITION(depth_test_enable, 0x12CC);
+ASSERT_REG_POSITION(fill_mode, 0x12D0);
+ASSERT_REG_POSITION(shade_mode, 0x12D4);
+ASSERT_REG_POSITION(l2_cache_rop_non_interlocked_writes, 0x12D8);
+ASSERT_REG_POSITION(l2_cache_rop_interlocked_writes, 0x12DC);
+ASSERT_REG_POSITION(alpha_to_coverage_dither, 0x12E0);
+ASSERT_REG_POSITION(blend_per_target_enabled, 0x12E4);
+ASSERT_REG_POSITION(depth_write_enabled, 0x12E8);
+ASSERT_REG_POSITION(alpha_test_enabled, 0x12EC);
+ASSERT_REG_POSITION(inline_index_4x8, 0x1300);
+ASSERT_REG_POSITION(d3d_cull_mode, 0x1308);
+ASSERT_REG_POSITION(depth_test_func, 0x130C);
+ASSERT_REG_POSITION(alpha_test_ref, 0x1310);
+ASSERT_REG_POSITION(alpha_test_func, 0x1314);
+ASSERT_REG_POSITION(draw_auto_stride, 0x1318);
+ASSERT_REG_POSITION(blend_color, 0x131C);
+ASSERT_REG_POSITION(invalidate_sampler_cache_lines, 0x1330);
+ASSERT_REG_POSITION(invalidate_texture_header_cache_lines, 0x1334);
+ASSERT_REG_POSITION(invalidate_texture_data_cache_lines, 0x1338);
+ASSERT_REG_POSITION(blend, 0x133C);
+ASSERT_REG_POSITION(stencil_enable, 0x1380);
+ASSERT_REG_POSITION(stencil_front_op, 0x1384);
+ASSERT_REG_POSITION(stencil_front_ref, 0x1394);
+ASSERT_REG_POSITION(stencil_front_func_mask, 0x1398);
+ASSERT_REG_POSITION(stencil_front_mask, 0x139C);
+ASSERT_REG_POSITION(draw_auto_start_byte_count, 0x13A4);
+ASSERT_REG_POSITION(frag_color_clamp, 0x13A8);
+ASSERT_REG_POSITION(window_origin, 0x13AC);
+ASSERT_REG_POSITION(line_width_smooth, 0x13B0);
+ASSERT_REG_POSITION(line_width_aliased, 0x13B4);
+ASSERT_REG_POSITION(line_override_multisample, 0x1418);
+ASSERT_REG_POSITION(alpha_hysteresis_rounds, 0x1420);
+ASSERT_REG_POSITION(invalidate_sampler_cache_no_wfi, 0x1424);
+ASSERT_REG_POSITION(invalidate_texture_header_cache_no_wfi, 0x1428);
+ASSERT_REG_POSITION(global_base_vertex_index, 0x1434);
+ASSERT_REG_POSITION(global_base_instance_index, 0x1438);
+ASSERT_REG_POSITION(ps_warp_watermarks, 0x1450);
+ASSERT_REG_POSITION(ps_regster_watermarks, 0x1454);
+ASSERT_REG_POSITION(store_zcull, 0x1464);
+ASSERT_REG_POSITION(iterated_blend_constants, 0x1480);
+ASSERT_REG_POSITION(load_zcull, 0x1500);
+ASSERT_REG_POSITION(surface_clip_id_height, 0x1504);
+ASSERT_REG_POSITION(surface_clip_id_clear_rect, 0x1508);
+ASSERT_REG_POSITION(user_clip_enable, 0x1510);
+ASSERT_REG_POSITION(zpass_pixel_count_enable, 0x1514);
+ASSERT_REG_POSITION(point_size, 0x1518);
+ASSERT_REG_POSITION(zcull_stats_enable, 0x151C);
+ASSERT_REG_POSITION(point_sprite_enable, 0x1520);
+ASSERT_REG_POSITION(shader_exceptions_enable, 0x1528);
+ASSERT_REG_POSITION(clear_report_value, 0x1530);
+ASSERT_REG_POSITION(anti_alias_enable, 0x1534);
+ASSERT_REG_POSITION(zeta_enable, 0x1538);
+ASSERT_REG_POSITION(anti_alias_alpha_control, 0x153C);
+ASSERT_REG_POSITION(render_enable, 0x1550);
+ASSERT_REG_POSITION(tex_sampler, 0x155C);
+ASSERT_REG_POSITION(slope_scale_depth_bias, 0x156C);
+ASSERT_REG_POSITION(line_anti_alias_enable, 0x1570);
+ASSERT_REG_POSITION(tex_header, 0x1574);
+ASSERT_REG_POSITION(active_zcull_region_id, 0x1590);
+ASSERT_REG_POSITION(stencil_two_side_enable, 0x1594);
+ASSERT_REG_POSITION(stencil_back_op, 0x1598);
+ASSERT_REG_POSITION(framebuffer_srgb, 0x15B8);
+ASSERT_REG_POSITION(depth_bias, 0x15BC);
+ASSERT_REG_POSITION(zcull_region_format, 0x15C8);
+ASSERT_REG_POSITION(rt_layer, 0x15CC);
+ASSERT_REG_POSITION(anti_alias_samples_mode, 0x15D0);
+ASSERT_REG_POSITION(edge_flag, 0x15E4);
+ASSERT_REG_POSITION(draw_inline_index, 0x15E8);
+ASSERT_REG_POSITION(inline_index_2x16, 0x15EC);
+ASSERT_REG_POSITION(vertex_global_base_offset, 0x15F4);
+ASSERT_REG_POSITION(zcull_region_pixel_offset, 0x15FC);
+ASSERT_REG_POSITION(point_sprite, 0x1604);
+ASSERT_REG_POSITION(program_region, 0x1608);
+ASSERT_REG_POSITION(default_attributes, 0x1610);
+ASSERT_REG_POSITION(draw, 0x1614);
+ASSERT_REG_POSITION(vertex_id_copy, 0x161C);
+ASSERT_REG_POSITION(add_to_primitive_id, 0x1620);
+ASSERT_REG_POSITION(load_to_primitive_id, 0x1624);
+ASSERT_REG_POSITION(shader_based_cull, 0x162C);
+ASSERT_REG_POSITION(class_version, 0x1638);
+ASSERT_REG_POSITION(primitive_restart, 0x1644);
+ASSERT_REG_POSITION(output_vertex_id, 0x164C);
+ASSERT_REG_POSITION(anti_alias_point_enable, 0x1658);
+ASSERT_REG_POSITION(point_center_mode, 0x165C);
+ASSERT_REG_POSITION(line_smooth_params, 0x1668);
+ASSERT_REG_POSITION(line_stipple_enable, 0x166C);
+ASSERT_REG_POSITION(line_smooth_edge_table, 0x1670);
+ASSERT_REG_POSITION(line_stipple_params, 0x1680);
+ASSERT_REG_POSITION(provoking_vertex, 0x1684);
+ASSERT_REG_POSITION(two_sided_light_enabled, 0x1688);
+ASSERT_REG_POSITION(polygon_stipple_enabled, 0x168C);
+ASSERT_REG_POSITION(shader_control, 0x1690);
+ASSERT_REG_POSITION(class_version_check, 0x16A0);
+ASSERT_REG_POSITION(sph_version, 0x16A4);
+ASSERT_REG_POSITION(sph_version_check, 0x16A8);
+ASSERT_REG_POSITION(alpha_to_coverage_override, 0x16B4);
+ASSERT_REG_POSITION(polygon_stipple_pattern, 0x1700);
+ASSERT_REG_POSITION(aam_version, 0x1790);
+ASSERT_REG_POSITION(aam_version_check, 0x1794);
+ASSERT_REG_POSITION(zeta_layer_offset, 0x179C);
+ASSERT_REG_POSITION(index_buffer, 0x17C8);
+ASSERT_REG_POSITION(index_buffer32_first, 0x17E4);
+ASSERT_REG_POSITION(index_buffer16_first, 0x17E8);
+ASSERT_REG_POSITION(index_buffer8_first, 0x17EC);
+ASSERT_REG_POSITION(index_buffer32_subsequent, 0x17F0);
+ASSERT_REG_POSITION(index_buffer16_subsequent, 0x17F4);
+ASSERT_REG_POSITION(index_buffer8_subsequent, 0x17F8);
+ASSERT_REG_POSITION(depth_bias_clamp, 0x187C);
+ASSERT_REG_POSITION(vertex_stream_instances, 0x1880);
+ASSERT_REG_POSITION(point_size_attribute, 0x1910);
+ASSERT_REG_POSITION(gl_cull_test_enabled, 0x1918);
+ASSERT_REG_POSITION(gl_front_face, 0x191C);
+ASSERT_REG_POSITION(gl_cull_face, 0x1920);
+ASSERT_REG_POSITION(viewport_pixel_center, 0x1924);
+ASSERT_REG_POSITION(viewport_scale_offset_enbled, 0x192C);
+ASSERT_REG_POSITION(viewport_clip_control, 0x193C);
+ASSERT_REG_POSITION(user_clip_op, 0x1940);
+ASSERT_REG_POSITION(render_enable_override, 0x1944);
+ASSERT_REG_POSITION(primitive_topology_control, 0x1948);
+ASSERT_REG_POSITION(window_clip_enable, 0x194C);
+ASSERT_REG_POSITION(invalidate_zcull, 0x1958);
+ASSERT_REG_POSITION(zcull, 0x1968);
+ASSERT_REG_POSITION(topology_override, 0x1970);
+ASSERT_REG_POSITION(zcull_sync, 0x1978);
+ASSERT_REG_POSITION(clip_id_test_enable, 0x197C);
+ASSERT_REG_POSITION(surface_clip_id_width, 0x1980);
+ASSERT_REG_POSITION(clip_id, 0x1984);
+ASSERT_REG_POSITION(depth_bounds_enable, 0x19BC);
+ASSERT_REG_POSITION(blend_float_zero_times_anything_is_zero, 0x19C0);
+ASSERT_REG_POSITION(logic_op, 0x19C4);
+ASSERT_REG_POSITION(z_compression_enable, 0x19CC);
+ASSERT_REG_POSITION(clear_surface, 0x19D0);
+ASSERT_REG_POSITION(clear_clip_id_surface, 0x19D4);
+ASSERT_REG_POSITION(color_compression_enable, 0x19E0);
+ASSERT_REG_POSITION(color_mask, 0x1A00);
+ASSERT_REG_POSITION(pipe_nop, 0x1A2C);
+ASSERT_REG_POSITION(spare, 0x1A30);
+ASSERT_REG_POSITION(report_semaphore, 0x1B00);
+ASSERT_REG_POSITION(vertex_streams, 0x1C00);
+ASSERT_REG_POSITION(blend_per_target, 0x1E00);
+ASSERT_REG_POSITION(vertex_stream_limits, 0x1F00);
+ASSERT_REG_POSITION(pipelines, 0x2000);
+ASSERT_REG_POSITION(falcon, 0x2300);
+ASSERT_REG_POSITION(const_buffer, 0x2380);
+ASSERT_REG_POSITION(bind_groups, 0x2400);
+ASSERT_REG_POSITION(color_clamp_enable, 0x2600);
+ASSERT_REG_POSITION(bindless_texture_const_buffer_slot, 0x2608);
+ASSERT_REG_POSITION(trap_handler, 0x260C);
+ASSERT_REG_POSITION(stream_out_layout, 0x2800);
+ASSERT_REG_POSITION(shader_performance, 0x333C);
+ASSERT_REG_POSITION(shadow_scratch, 0x3400);
#undef ASSERT_REG_POSITION
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index 0efe58282..4eb7a100d 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include "common/algorithm.h"
#include "common/assert.h"
#include "common/logging/log.h"
#include "common/microprofile.h"
@@ -54,90 +55,124 @@ void MaxwellDMA::Launch() {
const LaunchDMA& launch = regs.launch_dma;
ASSERT(launch.interrupt_type == LaunchDMA::InterruptType::NONE);
ASSERT(launch.data_transfer_type == LaunchDMA::DataTransferType::NON_PIPELINED);
- ASSERT(regs.dst_params.origin.x == 0);
- ASSERT(regs.dst_params.origin.y == 0);
- const bool is_src_pitch = launch.src_memory_layout == LaunchDMA::MemoryLayout::PITCH;
- const bool is_dst_pitch = launch.dst_memory_layout == LaunchDMA::MemoryLayout::PITCH;
+ if (launch.multi_line_enable) {
+ const bool is_src_pitch = launch.src_memory_layout == LaunchDMA::MemoryLayout::PITCH;
+ const bool is_dst_pitch = launch.dst_memory_layout == LaunchDMA::MemoryLayout::PITCH;
- if (!is_src_pitch && !is_dst_pitch) {
- // If both the source and the destination are in block layout, assert.
- UNIMPLEMENTED_MSG("Tiled->Tiled DMA transfers are not yet implemented");
- return;
- }
+ if (!is_src_pitch && !is_dst_pitch) {
+ // If both the source and the destination are in block layout, assert.
+ UNIMPLEMENTED_MSG("Tiled->Tiled DMA transfers are not yet implemented");
+ return;
+ }
- if (is_src_pitch && is_dst_pitch) {
- CopyPitchToPitch();
+ if (is_src_pitch && is_dst_pitch) {
+ for (u32 line = 0; line < regs.line_count; ++line) {
+ const GPUVAddr source_line =
+ regs.offset_in + static_cast<size_t>(line) * regs.pitch_in;
+ const GPUVAddr dest_line =
+ regs.offset_out + static_cast<size_t>(line) * regs.pitch_out;
+ memory_manager.CopyBlock(dest_line, source_line, regs.line_length_in);
+ }
+ } else {
+ if (!is_src_pitch && is_dst_pitch) {
+ CopyBlockLinearToPitch();
+ } else {
+ CopyPitchToBlockLinear();
+ }
+ }
} else {
- ASSERT(launch.multi_line_enable == 1);
-
- if (!is_src_pitch && is_dst_pitch) {
- CopyBlockLinearToPitch();
+ // TODO: allow multisized components.
+ auto& accelerate = rasterizer->AccessAccelerateDMA();
+ const bool is_const_a_dst = regs.remap_const.dst_x == RemapConst::Swizzle::CONST_A;
+ if (regs.launch_dma.remap_enable != 0 && is_const_a_dst) {
+ ASSERT(regs.remap_const.component_size_minus_one == 3);
+ accelerate.BufferClear(regs.offset_out, regs.line_length_in, regs.remap_consta_value);
+ std::vector<u32> tmp_buffer(regs.line_length_in, regs.remap_consta_value);
+ memory_manager.WriteBlockUnsafe(regs.offset_out,
+ reinterpret_cast<u8*>(tmp_buffer.data()),
+ regs.line_length_in * sizeof(u32));
} else {
- CopyPitchToBlockLinear();
+ auto convert_linear_2_blocklinear_addr = [](u64 address) {
+ return (address & ~0x1f0ULL) | ((address & 0x40) >> 2) | ((address & 0x10) << 1) |
+ ((address & 0x180) >> 1) | ((address & 0x20) << 3);
+ };
+ auto src_kind = memory_manager.GetPageKind(regs.offset_in);
+ auto dst_kind = memory_manager.GetPageKind(regs.offset_out);
+ const bool is_src_pitch = IsPitchKind(static_cast<PTEKind>(src_kind));
+ const bool is_dst_pitch = IsPitchKind(static_cast<PTEKind>(dst_kind));
+ if (!is_src_pitch && is_dst_pitch) {
+ std::vector<u8> tmp_buffer(regs.line_length_in);
+ std::vector<u8> dst_buffer(regs.line_length_in);
+ memory_manager.ReadBlockUnsafe(regs.offset_in, tmp_buffer.data(),
+ regs.line_length_in);
+ for (u32 offset = 0; offset < regs.line_length_in; ++offset) {
+ dst_buffer[offset] =
+ tmp_buffer[convert_linear_2_blocklinear_addr(regs.offset_in + offset) -
+ regs.offset_in];
+ }
+ memory_manager.WriteBlock(regs.offset_out, dst_buffer.data(), regs.line_length_in);
+ } else if (is_src_pitch && !is_dst_pitch) {
+ std::vector<u8> tmp_buffer(regs.line_length_in);
+ std::vector<u8> dst_buffer(regs.line_length_in);
+ memory_manager.ReadBlockUnsafe(regs.offset_in, tmp_buffer.data(),
+ regs.line_length_in);
+ for (u32 offset = 0; offset < regs.line_length_in; ++offset) {
+ dst_buffer[convert_linear_2_blocklinear_addr(regs.offset_out + offset) -
+ regs.offset_out] = tmp_buffer[offset];
+ }
+ memory_manager.WriteBlock(regs.offset_out, dst_buffer.data(), regs.line_length_in);
+ } else {
+ if (!accelerate.BufferCopy(regs.offset_in, regs.offset_out, regs.line_length_in)) {
+ std::vector<u8> tmp_buffer(regs.line_length_in);
+ memory_manager.ReadBlockUnsafe(regs.offset_in, tmp_buffer.data(),
+ regs.line_length_in);
+ memory_manager.WriteBlock(regs.offset_out, tmp_buffer.data(),
+ regs.line_length_in);
+ }
+ }
}
}
- ReleaseSemaphore();
-}
-void MaxwellDMA::CopyPitchToPitch() {
- // When `multi_line_enable` bit is enabled we copy a 2D image of dimensions
- // (line_length_in, line_count).
- // Otherwise the copy is performed as if we were copying a 1D buffer of length line_length_in.
- const bool remap_enabled = regs.launch_dma.remap_enable != 0;
- if (regs.launch_dma.multi_line_enable) {
- UNIMPLEMENTED_IF(remap_enabled);
-
- // Perform a line-by-line copy.
- // We're going to take a subrect of size (line_length_in, line_count) from the source
- // rectangle. There is no need to manually flush/invalidate the regions because CopyBlock
- // does that for us.
- for (u32 line = 0; line < regs.line_count; ++line) {
- const GPUVAddr source_line = regs.offset_in + static_cast<size_t>(line) * regs.pitch_in;
- const GPUVAddr dest_line = regs.offset_out + static_cast<size_t>(line) * regs.pitch_out;
- memory_manager.CopyBlock(dest_line, source_line, regs.line_length_in);
- }
- return;
- }
- // TODO: allow multisized components.
- auto& accelerate = rasterizer->AccessAccelerateDMA();
- const bool is_const_a_dst = regs.remap_const.dst_x == RemapConst::Swizzle::CONST_A;
- const bool is_buffer_clear = remap_enabled && is_const_a_dst;
- if (is_buffer_clear) {
- ASSERT(regs.remap_const.component_size_minus_one == 3);
- accelerate.BufferClear(regs.offset_out, regs.line_length_in, regs.remap_consta_value);
- std::vector<u32> tmp_buffer(regs.line_length_in, regs.remap_consta_value);
- memory_manager.WriteBlockUnsafe(regs.offset_out, reinterpret_cast<u8*>(tmp_buffer.data()),
- regs.line_length_in * sizeof(u32));
- return;
- }
- UNIMPLEMENTED_IF(remap_enabled);
- if (!accelerate.BufferCopy(regs.offset_in, regs.offset_out, regs.line_length_in)) {
- std::vector<u8> tmp_buffer(regs.line_length_in);
- memory_manager.ReadBlockUnsafe(regs.offset_in, tmp_buffer.data(), regs.line_length_in);
- memory_manager.WriteBlock(regs.offset_out, tmp_buffer.data(), regs.line_length_in);
- }
+ ReleaseSemaphore();
}
void MaxwellDMA::CopyBlockLinearToPitch() {
UNIMPLEMENTED_IF(regs.src_params.block_size.width != 0);
- UNIMPLEMENTED_IF(regs.src_params.block_size.depth != 0);
UNIMPLEMENTED_IF(regs.src_params.layer != 0);
+ const bool is_remapping = regs.launch_dma.remap_enable != 0;
+
// Optimized path for micro copies.
const size_t dst_size = static_cast<size_t>(regs.pitch_out) * regs.line_count;
- if (dst_size < GOB_SIZE && regs.pitch_out <= GOB_SIZE_X &&
+ if (!is_remapping && dst_size < GOB_SIZE && regs.pitch_out <= GOB_SIZE_X &&
regs.src_params.height > GOB_SIZE_Y) {
FastCopyBlockLinearToPitch();
return;
}
// Deswizzle the input and copy it over.
- UNIMPLEMENTED_IF(regs.launch_dma.remap_enable != 0);
- const u32 bytes_per_pixel =
- regs.launch_dma.remap_enable ? regs.pitch_out / regs.line_length_in : 1;
const Parameters& src_params = regs.src_params;
- const u32 width = src_params.width;
+
+ const u32 num_remap_components = regs.remap_const.num_dst_components_minus_one + 1;
+ const u32 remap_components_size = regs.remap_const.component_size_minus_one + 1;
+
+ const u32 base_bpp = !is_remapping ? 1U : num_remap_components * remap_components_size;
+
+ u32 width = src_params.width;
+ u32 x_elements = regs.line_length_in;
+ u32 x_offset = src_params.origin.x;
+ u32 bpp_shift = 0U;
+ if (!is_remapping) {
+ bpp_shift = Common::FoldRight(
+ 4U, [](u32 x, u32 y) { return std::min(x, static_cast<u32>(std::countr_zero(y))); },
+ width, x_elements, x_offset, static_cast<u32>(regs.offset_in));
+ width >>= bpp_shift;
+ x_elements >>= bpp_shift;
+ x_offset >>= bpp_shift;
+ }
+
+ const u32 bytes_per_pixel = base_bpp << bpp_shift;
const u32 height = src_params.height;
const u32 depth = src_params.depth;
const u32 block_height = src_params.block_size.height;
@@ -155,30 +190,45 @@ void MaxwellDMA::CopyBlockLinearToPitch() {
memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size);
memory_manager.ReadBlock(regs.offset_out, write_buffer.data(), dst_size);
- UnswizzleSubrect(regs.line_length_in, regs.line_count, regs.pitch_out, width, bytes_per_pixel,
- block_height, src_params.origin.x, src_params.origin.y, write_buffer.data(),
- read_buffer.data());
+ UnswizzleSubrect(write_buffer, read_buffer, bytes_per_pixel, width, height, depth, x_offset,
+ src_params.origin.y, x_elements, regs.line_count, block_height, block_depth,
+ regs.pitch_out);
memory_manager.WriteBlock(regs.offset_out, write_buffer.data(), dst_size);
}
void MaxwellDMA::CopyPitchToBlockLinear() {
UNIMPLEMENTED_IF_MSG(regs.dst_params.block_size.width != 0, "Block width is not one");
- UNIMPLEMENTED_IF(regs.launch_dma.remap_enable != 0);
+ UNIMPLEMENTED_IF(regs.dst_params.layer != 0);
+
+ const bool is_remapping = regs.launch_dma.remap_enable != 0;
+ const u32 num_remap_components = regs.remap_const.num_dst_components_minus_one + 1;
+ const u32 remap_components_size = regs.remap_const.component_size_minus_one + 1;
const auto& dst_params = regs.dst_params;
- const u32 bytes_per_pixel =
- regs.launch_dma.remap_enable ? regs.pitch_in / regs.line_length_in : 1;
- const u32 width = dst_params.width;
+
+ const u32 base_bpp = !is_remapping ? 1U : num_remap_components * remap_components_size;
+
+ u32 width = dst_params.width;
+ u32 x_elements = regs.line_length_in;
+ u32 x_offset = dst_params.origin.x;
+ u32 bpp_shift = 0U;
+ if (!is_remapping) {
+ bpp_shift = Common::FoldRight(
+ 4U, [](u32 x, u32 y) { return std::min(x, static_cast<u32>(std::countr_zero(y))); },
+ width, x_elements, x_offset, static_cast<u32>(regs.offset_out));
+ width >>= bpp_shift;
+ x_elements >>= bpp_shift;
+ x_offset >>= bpp_shift;
+ }
+
+ const u32 bytes_per_pixel = base_bpp << bpp_shift;
const u32 height = dst_params.height;
const u32 depth = dst_params.depth;
const u32 block_height = dst_params.block_size.height;
const u32 block_depth = dst_params.block_size.depth;
const size_t dst_size =
CalculateSize(true, bytes_per_pixel, width, height, depth, block_height, block_depth);
- const size_t dst_layer_size =
- CalculateSize(true, bytes_per_pixel, width, height, 1, block_height, block_depth);
-
const size_t src_size = static_cast<size_t>(regs.pitch_in) * regs.line_count;
if (read_buffer.size() < src_size) {
@@ -188,32 +238,23 @@ void MaxwellDMA::CopyPitchToBlockLinear() {
write_buffer.resize(dst_size);
}
+ memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size);
if (Settings::IsGPULevelExtreme()) {
- memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size);
memory_manager.ReadBlock(regs.offset_out, write_buffer.data(), dst_size);
} else {
- memory_manager.ReadBlockUnsafe(regs.offset_in, read_buffer.data(), src_size);
memory_manager.ReadBlockUnsafe(regs.offset_out, write_buffer.data(), dst_size);
}
// If the input is linear and the output is tiled, swizzle the input and copy it over.
- if (regs.dst_params.block_size.depth > 0) {
- ASSERT(dst_params.layer == 0);
- SwizzleSliceToVoxel(regs.line_length_in, regs.line_count, regs.pitch_in, width, height,
- bytes_per_pixel, block_height, block_depth, dst_params.origin.x,
- dst_params.origin.y, write_buffer.data(), read_buffer.data());
- } else {
- SwizzleSubrect(regs.line_length_in, regs.line_count, regs.pitch_in, width, bytes_per_pixel,
- write_buffer.data() + dst_layer_size * dst_params.layer, read_buffer.data(),
- block_height, dst_params.origin.x, dst_params.origin.y);
- }
+ SwizzleSubrect(write_buffer, read_buffer, bytes_per_pixel, width, height, depth, x_offset,
+ dst_params.origin.y, x_elements, regs.line_count, block_height, block_depth,
+ regs.pitch_in);
memory_manager.WriteBlock(regs.offset_out, write_buffer.data(), dst_size);
}
void MaxwellDMA::FastCopyBlockLinearToPitch() {
- const u32 bytes_per_pixel =
- regs.launch_dma.remap_enable ? regs.pitch_out / regs.line_length_in : 1;
+ const u32 bytes_per_pixel = 1U;
const size_t src_size = GOB_SIZE;
const size_t dst_size = static_cast<size_t>(regs.pitch_out) * regs.line_count;
u32 pos_x = regs.src_params.origin.x;
@@ -239,9 +280,10 @@ void MaxwellDMA::FastCopyBlockLinearToPitch() {
memory_manager.ReadBlockUnsafe(regs.offset_out, write_buffer.data(), dst_size);
}
- UnswizzleSubrect(regs.line_length_in, regs.line_count, regs.pitch_out, regs.src_params.width,
- bytes_per_pixel, regs.src_params.block_size.height, pos_x, pos_y,
- write_buffer.data(), read_buffer.data());
+ UnswizzleSubrect(write_buffer, read_buffer, bytes_per_pixel, regs.src_params.width,
+ regs.src_params.height, 1, pos_x, pos_y, regs.line_length_in, regs.line_count,
+ regs.src_params.block_size.height, regs.src_params.block_size.depth,
+ regs.pitch_out);
memory_manager.WriteBlock(regs.offset_out, write_buffer.data(), dst_size);
}
@@ -249,16 +291,24 @@ void MaxwellDMA::FastCopyBlockLinearToPitch() {
void MaxwellDMA::ReleaseSemaphore() {
const auto type = regs.launch_dma.semaphore_type;
const GPUVAddr address = regs.semaphore.address;
+ const u32 payload = regs.semaphore.payload;
switch (type) {
case LaunchDMA::SemaphoreType::NONE:
break;
- case LaunchDMA::SemaphoreType::RELEASE_ONE_WORD_SEMAPHORE:
- memory_manager.Write<u32>(address, regs.semaphore.payload);
+ case LaunchDMA::SemaphoreType::RELEASE_ONE_WORD_SEMAPHORE: {
+ std::function<void()> operation(
+ [this, address, payload] { memory_manager.Write<u32>(address, payload); });
+ rasterizer->SignalFence(std::move(operation));
break;
- case LaunchDMA::SemaphoreType::RELEASE_FOUR_WORD_SEMAPHORE:
- memory_manager.Write<u64>(address, static_cast<u64>(regs.semaphore.payload));
- memory_manager.Write<u64>(address + 8, system.GPU().GetTicks());
+ }
+ case LaunchDMA::SemaphoreType::RELEASE_FOUR_WORD_SEMAPHORE: {
+ std::function<void()> operation([this, address, payload] {
+ memory_manager.Write<u64>(address + sizeof(u64), system.GPU().GetTicks());
+ memory_manager.Write<u64>(address, payload);
+ });
+ rasterizer->SignalFence(std::move(operation));
break;
+ }
default:
ASSERT_MSG(false, "Unknown semaphore type: {}", static_cast<u32>(type.Value()));
}
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h
index 074bac92c..953e34adc 100644
--- a/src/video_core/engines/maxwell_dma.h
+++ b/src/video_core/engines/maxwell_dma.h
@@ -189,10 +189,16 @@ public:
BitField<4, 3, Swizzle> dst_y;
BitField<8, 3, Swizzle> dst_z;
BitField<12, 3, Swizzle> dst_w;
+ BitField<0, 12, u32> dst_components_raw;
BitField<16, 2, u32> component_size_minus_one;
BitField<20, 2, u32> num_src_components_minus_one;
BitField<24, 2, u32> num_dst_components_minus_one;
};
+
+ Swizzle GetComponent(size_t i) const {
+ const u32 raw = dst_components_raw;
+ return static_cast<Swizzle>((raw >> (i * 3)) & 0x7);
+ }
};
static_assert(sizeof(RemapConst) == 12);
@@ -213,8 +219,6 @@ private:
/// registers.
void Launch();
- void CopyPitchToPitch();
-
void CopyBlockLinearToPitch();
void CopyPitchToBlockLinear();
diff --git a/src/video_core/engines/puller.cpp b/src/video_core/engines/puller.cpp
new file mode 100644
index 000000000..3977bb0fb
--- /dev/null
+++ b/src/video_core/engines/puller.cpp
@@ -0,0 +1,305 @@
+// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "common/assert.h"
+#include "common/logging/log.h"
+#include "common/settings.h"
+#include "core/core.h"
+#include "video_core/control/channel_state.h"
+#include "video_core/dma_pusher.h"
+#include "video_core/engines/fermi_2d.h"
+#include "video_core/engines/kepler_compute.h"
+#include "video_core/engines/kepler_memory.h"
+#include "video_core/engines/maxwell_3d.h"
+#include "video_core/engines/maxwell_dma.h"
+#include "video_core/engines/puller.h"
+#include "video_core/gpu.h"
+#include "video_core/memory_manager.h"
+#include "video_core/rasterizer_interface.h"
+
+namespace Tegra::Engines {
+
+Puller::Puller(GPU& gpu_, MemoryManager& memory_manager_, DmaPusher& dma_pusher_,
+ Control::ChannelState& channel_state_)
+ : gpu{gpu_}, memory_manager{memory_manager_}, dma_pusher{dma_pusher_}, channel_state{
+ channel_state_} {}
+
+Puller::~Puller() = default;
+
+void Puller::ProcessBindMethod(const MethodCall& method_call) {
+ // Bind the current subchannel to the desired engine id.
+ LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", method_call.subchannel,
+ method_call.argument);
+ const auto engine_id = static_cast<EngineID>(method_call.argument);
+ bound_engines[method_call.subchannel] = static_cast<EngineID>(engine_id);
+ switch (engine_id) {
+ case EngineID::FERMI_TWOD_A:
+ dma_pusher.BindSubchannel(channel_state.fermi_2d.get(), method_call.subchannel);
+ break;
+ case EngineID::MAXWELL_B:
+ dma_pusher.BindSubchannel(channel_state.maxwell_3d.get(), method_call.subchannel);
+ break;
+ case EngineID::KEPLER_COMPUTE_B:
+ dma_pusher.BindSubchannel(channel_state.kepler_compute.get(), method_call.subchannel);
+ break;
+ case EngineID::MAXWELL_DMA_COPY_A:
+ dma_pusher.BindSubchannel(channel_state.maxwell_dma.get(), method_call.subchannel);
+ break;
+ case EngineID::KEPLER_INLINE_TO_MEMORY_B:
+ dma_pusher.BindSubchannel(channel_state.kepler_memory.get(), method_call.subchannel);
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unimplemented engine {:04X}", engine_id);
+ }
+}
+
+void Puller::ProcessFenceActionMethod() {
+ switch (regs.fence_action.op) {
+ case Puller::FenceOperation::Acquire:
+ // UNIMPLEMENTED_MSG("Channel Scheduling pending.");
+ // WaitFence(regs.fence_action.syncpoint_id, regs.fence_value);
+ rasterizer->ReleaseFences();
+ break;
+ case Puller::FenceOperation::Increment:
+ rasterizer->SignalSyncPoint(regs.fence_action.syncpoint_id);
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unimplemented operation {}", regs.fence_action.op.Value());
+ }
+}
+
+void Puller::ProcessSemaphoreTriggerMethod() {
+ const auto semaphoreOperationMask = 0xF;
+ const auto op =
+ static_cast<GpuSemaphoreOperation>(regs.semaphore_trigger & semaphoreOperationMask);
+ if (op == GpuSemaphoreOperation::WriteLong) {
+ const GPUVAddr sequence_address{regs.semaphore_address.SemaphoreAddress()};
+ const u32 payload = regs.semaphore_sequence;
+ [this, sequence_address, payload] {
+ memory_manager.Write<u64>(sequence_address + sizeof(u64), gpu.GetTicks());
+ memory_manager.Write<u64>(sequence_address, payload);
+ }();
+ } else {
+ do {
+ const u32 word{memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress())};
+ regs.acquire_source = true;
+ regs.acquire_value = regs.semaphore_sequence;
+ if (op == GpuSemaphoreOperation::AcquireEqual) {
+ regs.acquire_active = true;
+ regs.acquire_mode = false;
+ if (word != regs.acquire_value) {
+ rasterizer->ReleaseFences();
+ continue;
+ }
+ } else if (op == GpuSemaphoreOperation::AcquireGequal) {
+ regs.acquire_active = true;
+ regs.acquire_mode = true;
+ if (word < regs.acquire_value) {
+ rasterizer->ReleaseFences();
+ continue;
+ }
+ } else if (op == GpuSemaphoreOperation::AcquireMask) {
+ if (word && regs.semaphore_sequence == 0) {
+ rasterizer->ReleaseFences();
+ continue;
+ }
+ } else {
+ LOG_ERROR(HW_GPU, "Invalid semaphore operation");
+ }
+ } while (false);
+ }
+}
+
+void Puller::ProcessSemaphoreRelease() {
+ const GPUVAddr sequence_address{regs.semaphore_address.SemaphoreAddress()};
+ const u32 payload = regs.semaphore_release;
+ std::function<void()> operation([this, sequence_address, payload] {
+ memory_manager.Write<u32>(sequence_address, payload);
+ });
+ rasterizer->SyncOperation(std::move(operation));
+}
+
+void Puller::ProcessSemaphoreAcquire() {
+ u32 word = memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress());
+ const auto value = regs.semaphore_acquire;
+ while (word != value) {
+ regs.acquire_active = true;
+ regs.acquire_value = value;
+ std::this_thread::sleep_for(std::chrono::milliseconds(1));
+ rasterizer->ReleaseFences();
+ word = memory_manager.Read<u32>(regs.semaphore_address.SemaphoreAddress());
+ // TODO(kemathe73) figure out how to do the acquire_timeout
+ regs.acquire_mode = false;
+ regs.acquire_source = false;
+ }
+}
+
+/// Calls a GPU puller method.
+void Puller::CallPullerMethod(const MethodCall& method_call) {
+ regs.reg_array[method_call.method] = method_call.argument;
+ const auto method = static_cast<BufferMethods>(method_call.method);
+
+ switch (method) {
+ case BufferMethods::BindObject: {
+ ProcessBindMethod(method_call);
+ break;
+ }
+ case BufferMethods::Nop:
+ case BufferMethods::SemaphoreAddressHigh:
+ case BufferMethods::SemaphoreAddressLow:
+ case BufferMethods::SemaphoreSequencePayload:
+ case BufferMethods::SyncpointPayload:
+ break;
+ case BufferMethods::WrcacheFlush:
+ case BufferMethods::RefCnt:
+ rasterizer->SignalReference();
+ break;
+ case BufferMethods::SyncpointOperation:
+ ProcessFenceActionMethod();
+ break;
+ case BufferMethods::WaitForIdle:
+ rasterizer->WaitForIdle();
+ break;
+ case BufferMethods::SemaphoreOperation: {
+ ProcessSemaphoreTriggerMethod();
+ break;
+ }
+ case BufferMethods::NonStallInterrupt: {
+ LOG_ERROR(HW_GPU, "Special puller engine method NonStallInterrupt not implemented");
+ break;
+ }
+ case BufferMethods::MemOpA: {
+ LOG_ERROR(HW_GPU, "Memory Operation A");
+ break;
+ }
+ case BufferMethods::MemOpB: {
+ // Implement this better.
+ rasterizer->InvalidateGPUCache();
+ break;
+ }
+ case BufferMethods::MemOpC:
+ case BufferMethods::MemOpD: {
+ LOG_ERROR(HW_GPU, "Memory Operation C,D");
+ break;
+ }
+ case BufferMethods::SemaphoreAcquire: {
+ ProcessSemaphoreAcquire();
+ break;
+ }
+ case BufferMethods::SemaphoreRelease: {
+ ProcessSemaphoreRelease();
+ break;
+ }
+ case BufferMethods::Yield: {
+ // TODO(Kmather73): Research and implement this method.
+ LOG_ERROR(HW_GPU, "Special puller engine method Yield not implemented");
+ break;
+ }
+ default:
+ LOG_ERROR(HW_GPU, "Special puller engine method {:X} not implemented", method);
+ break;
+ }
+}
+
+/// Calls a GPU engine method.
+void Puller::CallEngineMethod(const MethodCall& method_call) {
+ const EngineID engine = bound_engines[method_call.subchannel];
+
+ switch (engine) {
+ case EngineID::FERMI_TWOD_A:
+ channel_state.fermi_2d->CallMethod(method_call.method, method_call.argument,
+ method_call.IsLastCall());
+ break;
+ case EngineID::MAXWELL_B:
+ channel_state.maxwell_3d->CallMethod(method_call.method, method_call.argument,
+ method_call.IsLastCall());
+ break;
+ case EngineID::KEPLER_COMPUTE_B:
+ channel_state.kepler_compute->CallMethod(method_call.method, method_call.argument,
+ method_call.IsLastCall());
+ break;
+ case EngineID::MAXWELL_DMA_COPY_A:
+ channel_state.maxwell_dma->CallMethod(method_call.method, method_call.argument,
+ method_call.IsLastCall());
+ break;
+ case EngineID::KEPLER_INLINE_TO_MEMORY_B:
+ channel_state.kepler_memory->CallMethod(method_call.method, method_call.argument,
+ method_call.IsLastCall());
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unimplemented engine");
+ }
+}
+
+/// Calls a GPU engine multivalue method.
+void Puller::CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount,
+ u32 methods_pending) {
+ const EngineID engine = bound_engines[subchannel];
+
+ switch (engine) {
+ case EngineID::FERMI_TWOD_A:
+ channel_state.fermi_2d->CallMultiMethod(method, base_start, amount, methods_pending);
+ break;
+ case EngineID::MAXWELL_B:
+ channel_state.maxwell_3d->CallMultiMethod(method, base_start, amount, methods_pending);
+ break;
+ case EngineID::KEPLER_COMPUTE_B:
+ channel_state.kepler_compute->CallMultiMethod(method, base_start, amount, methods_pending);
+ break;
+ case EngineID::MAXWELL_DMA_COPY_A:
+ channel_state.maxwell_dma->CallMultiMethod(method, base_start, amount, methods_pending);
+ break;
+ case EngineID::KEPLER_INLINE_TO_MEMORY_B:
+ channel_state.kepler_memory->CallMultiMethod(method, base_start, amount, methods_pending);
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unimplemented engine");
+ }
+}
+
+/// Calls a GPU method.
+void Puller::CallMethod(const MethodCall& method_call) {
+ LOG_TRACE(HW_GPU, "Processing method {:08X} on subchannel {}", method_call.method,
+ method_call.subchannel);
+
+ ASSERT(method_call.subchannel < bound_engines.size());
+
+ if (ExecuteMethodOnEngine(method_call.method)) {
+ CallEngineMethod(method_call);
+ } else {
+ CallPullerMethod(method_call);
+ }
+}
+
+/// Calls a GPU multivalue method.
+void Puller::CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount,
+ u32 methods_pending) {
+ LOG_TRACE(HW_GPU, "Processing method {:08X} on subchannel {}", method, subchannel);
+
+ ASSERT(subchannel < bound_engines.size());
+
+ if (ExecuteMethodOnEngine(method)) {
+ CallEngineMultiMethod(method, subchannel, base_start, amount, methods_pending);
+ } else {
+ for (std::size_t i = 0; i < amount; i++) {
+ CallPullerMethod(MethodCall{
+ method,
+ base_start[i],
+ subchannel,
+ methods_pending - static_cast<u32>(i),
+ });
+ }
+ }
+}
+
+void Puller::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) {
+ rasterizer = rasterizer_;
+}
+
+/// Determines where the method should be executed.
+[[nodiscard]] bool Puller::ExecuteMethodOnEngine(u32 method) {
+ const auto buffer_method = static_cast<BufferMethods>(method);
+ return buffer_method >= BufferMethods::NonPullerMethods;
+}
+
+} // namespace Tegra::Engines
diff --git a/src/video_core/engines/puller.h b/src/video_core/engines/puller.h
new file mode 100644
index 000000000..d4175ee94
--- /dev/null
+++ b/src/video_core/engines/puller.h
@@ -0,0 +1,177 @@
+// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <array>
+#include <cstddef>
+#include <vector>
+#include "common/bit_field.h"
+#include "common/common_funcs.h"
+#include "common/common_types.h"
+#include "video_core/engines/engine_interface.h"
+
+namespace Core {
+class System;
+}
+
+namespace Tegra {
+class MemoryManager;
+class DmaPusher;
+
+enum class EngineID {
+ FERMI_TWOD_A = 0x902D, // 2D Engine
+ MAXWELL_B = 0xB197, // 3D Engine
+ KEPLER_COMPUTE_B = 0xB1C0,
+ KEPLER_INLINE_TO_MEMORY_B = 0xA140,
+ MAXWELL_DMA_COPY_A = 0xB0B5,
+};
+
+namespace Control {
+struct ChannelState;
+}
+} // namespace Tegra
+
+namespace VideoCore {
+class RasterizerInterface;
+}
+
+namespace Tegra::Engines {
+
+class Puller final {
+public:
+ struct MethodCall {
+ u32 method{};
+ u32 argument{};
+ u32 subchannel{};
+ u32 method_count{};
+
+ explicit MethodCall(u32 method_, u32 argument_, u32 subchannel_ = 0, u32 method_count_ = 0)
+ : method(method_), argument(argument_), subchannel(subchannel_),
+ method_count(method_count_) {}
+
+ [[nodiscard]] bool IsLastCall() const {
+ return method_count <= 1;
+ }
+ };
+
+ enum class FenceOperation : u32 {
+ Acquire = 0,
+ Increment = 1,
+ };
+
+ union FenceAction {
+ u32 raw;
+ BitField<0, 1, FenceOperation> op;
+ BitField<8, 24, u32> syncpoint_id;
+ };
+
+ explicit Puller(GPU& gpu_, MemoryManager& memory_manager_, DmaPusher& dma_pusher,
+ Control::ChannelState& channel_state);
+ ~Puller();
+
+ void CallMethod(const MethodCall& method_call);
+
+ void CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount,
+ u32 methods_pending);
+
+ void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
+
+ void CallPullerMethod(const MethodCall& method_call);
+
+ void CallEngineMethod(const MethodCall& method_call);
+
+ void CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount,
+ u32 methods_pending);
+
+private:
+ Tegra::GPU& gpu;
+
+ MemoryManager& memory_manager;
+ DmaPusher& dma_pusher;
+ Control::ChannelState& channel_state;
+ VideoCore::RasterizerInterface* rasterizer = nullptr;
+
+ static constexpr std::size_t NUM_REGS = 0x800;
+ struct Regs {
+ static constexpr size_t NUM_REGS = 0x40;
+
+ union {
+ struct {
+ INSERT_PADDING_WORDS_NOINIT(0x4);
+ struct {
+ u32 address_high;
+ u32 address_low;
+
+ [[nodiscard]] GPUVAddr SemaphoreAddress() const {
+ return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
+ address_low);
+ }
+ } semaphore_address;
+
+ u32 semaphore_sequence;
+ u32 semaphore_trigger;
+ INSERT_PADDING_WORDS_NOINIT(0xC);
+
+ // The pusher and the puller share the reference counter, the pusher only has read
+ // access
+ u32 reference_count;
+ INSERT_PADDING_WORDS_NOINIT(0x5);
+
+ u32 semaphore_acquire;
+ u32 semaphore_release;
+ u32 fence_value;
+ FenceAction fence_action;
+ INSERT_PADDING_WORDS_NOINIT(0xE2);
+
+ // Puller state
+ u32 acquire_mode;
+ u32 acquire_source;
+ u32 acquire_active;
+ u32 acquire_timeout;
+ u32 acquire_value;
+ };
+ std::array<u32, NUM_REGS> reg_array;
+ };
+ } regs{};
+
+ void ProcessBindMethod(const MethodCall& method_call);
+ void ProcessFenceActionMethod();
+ void ProcessSemaphoreAcquire();
+ void ProcessSemaphoreRelease();
+ void ProcessSemaphoreTriggerMethod();
+ [[nodiscard]] bool ExecuteMethodOnEngine(u32 method);
+
+ /// Mapping of command subchannels to their bound engine ids
+ std::array<EngineID, 8> bound_engines{};
+
+ enum class GpuSemaphoreOperation {
+ AcquireEqual = 0x1,
+ WriteLong = 0x2,
+ AcquireGequal = 0x4,
+ AcquireMask = 0x8,
+ };
+
+#define ASSERT_REG_POSITION(field_name, position) \
+ static_assert(offsetof(Regs, field_name) == position * 4, \
+ "Field " #field_name " has invalid position")
+
+ ASSERT_REG_POSITION(semaphore_address, 0x4);
+ ASSERT_REG_POSITION(semaphore_sequence, 0x6);
+ ASSERT_REG_POSITION(semaphore_trigger, 0x7);
+ ASSERT_REG_POSITION(reference_count, 0x14);
+ ASSERT_REG_POSITION(semaphore_acquire, 0x1A);
+ ASSERT_REG_POSITION(semaphore_release, 0x1B);
+ ASSERT_REG_POSITION(fence_value, 0x1C);
+ ASSERT_REG_POSITION(fence_action, 0x1D);
+
+ ASSERT_REG_POSITION(acquire_mode, 0x100);
+ ASSERT_REG_POSITION(acquire_source, 0x101);
+ ASSERT_REG_POSITION(acquire_active, 0x102);
+ ASSERT_REG_POSITION(acquire_timeout, 0x103);
+ ASSERT_REG_POSITION(acquire_value, 0x104);
+
+#undef ASSERT_REG_POSITION
+};
+
+} // namespace Tegra::Engines
diff --git a/src/video_core/fence_manager.h b/src/video_core/fence_manager.h
index 1e9832ddd..c390ac91b 100644
--- a/src/video_core/fence_manager.h
+++ b/src/video_core/fence_manager.h
@@ -4,40 +4,24 @@
#pragma once
#include <algorithm>
+#include <cstring>
+#include <deque>
+#include <functional>
+#include <memory>
#include <queue>
#include "common/common_types.h"
#include "video_core/delayed_destruction_ring.h"
#include "video_core/gpu.h"
-#include "video_core/memory_manager.h"
+#include "video_core/host1x/host1x.h"
+#include "video_core/host1x/syncpoint_manager.h"
#include "video_core/rasterizer_interface.h"
namespace VideoCommon {
class FenceBase {
public:
- explicit FenceBase(u32 payload_, bool is_stubbed_)
- : address{}, payload{payload_}, is_semaphore{false}, is_stubbed{is_stubbed_} {}
-
- explicit FenceBase(GPUVAddr address_, u32 payload_, bool is_stubbed_)
- : address{address_}, payload{payload_}, is_semaphore{true}, is_stubbed{is_stubbed_} {}
-
- GPUVAddr GetAddress() const {
- return address;
- }
-
- u32 GetPayload() const {
- return payload;
- }
-
- bool IsSemaphore() const {
- return is_semaphore;
- }
-
-private:
- GPUVAddr address;
- u32 payload;
- bool is_semaphore;
+ explicit FenceBase(bool is_stubbed_) : is_stubbed{is_stubbed_} {}
protected:
bool is_stubbed;
@@ -57,30 +41,28 @@ public:
buffer_cache.AccumulateFlushes();
}
- void SignalSemaphore(GPUVAddr addr, u32 value) {
+ void SyncOperation(std::function<void()>&& func) {
+ uncommitted_operations.emplace_back(std::move(func));
+ }
+
+ void SignalFence(std::function<void()>&& func) {
TryReleasePendingFences();
const bool should_flush = ShouldFlush();
CommitAsyncFlushes();
- TFence new_fence = CreateFence(addr, value, !should_flush);
+ uncommitted_operations.emplace_back(std::move(func));
+ CommitOperations();
+ TFence new_fence = CreateFence(!should_flush);
fences.push(new_fence);
QueueFence(new_fence);
if (should_flush) {
rasterizer.FlushCommands();
}
- rasterizer.SyncGuestHost();
}
void SignalSyncPoint(u32 value) {
- TryReleasePendingFences();
- const bool should_flush = ShouldFlush();
- CommitAsyncFlushes();
- TFence new_fence = CreateFence(value, !should_flush);
- fences.push(new_fence);
- QueueFence(new_fence);
- if (should_flush) {
- rasterizer.FlushCommands();
- }
- rasterizer.SyncGuestHost();
+ syncpoint_manager.IncrementGuest(value);
+ std::function<void()> func([this, value] { syncpoint_manager.IncrementHost(value); });
+ SignalFence(std::move(func));
}
void WaitPendingFences() {
@@ -90,11 +72,10 @@ public:
WaitFence(current_fence);
}
PopAsyncFlushes();
- if (current_fence->IsSemaphore()) {
- gpu_memory.template Write<u32>(current_fence->GetAddress(),
- current_fence->GetPayload());
- } else {
- gpu.IncrementSyncPoint(current_fence->GetPayload());
+ auto operations = std::move(pending_operations.front());
+ pending_operations.pop_front();
+ for (auto& operation : operations) {
+ operation();
}
PopFence();
}
@@ -104,16 +85,14 @@ protected:
explicit FenceManager(VideoCore::RasterizerInterface& rasterizer_, Tegra::GPU& gpu_,
TTextureCache& texture_cache_, TTBufferCache& buffer_cache_,
TQueryCache& query_cache_)
- : rasterizer{rasterizer_}, gpu{gpu_}, gpu_memory{gpu.MemoryManager()},
+ : rasterizer{rasterizer_}, gpu{gpu_}, syncpoint_manager{gpu.Host1x().GetSyncpointManager()},
texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, query_cache{query_cache_} {}
virtual ~FenceManager() = default;
- /// Creates a Sync Point Fence Interface, does not create a backend fence if 'is_stubbed' is
+ /// Creates a Fence Interface, does not create a backend fence if 'is_stubbed' is
/// true
- virtual TFence CreateFence(u32 value, bool is_stubbed) = 0;
- /// Creates a Semaphore Fence Interface, does not create a backend fence if 'is_stubbed' is true
- virtual TFence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) = 0;
+ virtual TFence CreateFence(bool is_stubbed) = 0;
/// Queues a fence into the backend if the fence isn't stubbed.
virtual void QueueFence(TFence& fence) = 0;
/// Notifies that the backend fence has been signaled/reached in host GPU.
@@ -123,7 +102,7 @@ protected:
VideoCore::RasterizerInterface& rasterizer;
Tegra::GPU& gpu;
- Tegra::MemoryManager& gpu_memory;
+ Tegra::Host1x::SyncpointManager& syncpoint_manager;
TTextureCache& texture_cache;
TTBufferCache& buffer_cache;
TQueryCache& query_cache;
@@ -136,11 +115,10 @@ private:
return;
}
PopAsyncFlushes();
- if (current_fence->IsSemaphore()) {
- gpu_memory.template Write<u32>(current_fence->GetAddress(),
- current_fence->GetPayload());
- } else {
- gpu.IncrementSyncPoint(current_fence->GetPayload());
+ auto operations = std::move(pending_operations.front());
+ pending_operations.pop_front();
+ for (auto& operation : operations) {
+ operation();
}
PopFence();
}
@@ -159,16 +137,20 @@ private:
}
void PopAsyncFlushes() {
- std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
- texture_cache.PopAsyncFlushes();
- buffer_cache.PopAsyncFlushes();
+ {
+ std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ texture_cache.PopAsyncFlushes();
+ buffer_cache.PopAsyncFlushes();
+ }
query_cache.PopAsyncFlushes();
}
void CommitAsyncFlushes() {
- std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
- texture_cache.CommitAsyncFlushes();
- buffer_cache.CommitAsyncFlushes();
+ {
+ std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ texture_cache.CommitAsyncFlushes();
+ buffer_cache.CommitAsyncFlushes();
+ }
query_cache.CommitAsyncFlushes();
}
@@ -177,7 +159,13 @@ private:
fences.pop();
}
+ void CommitOperations() {
+ pending_operations.emplace_back(std::move(uncommitted_operations));
+ }
+
std::queue<TFence> fences;
+ std::deque<std::function<void()>> uncommitted_operations;
+ std::deque<std::deque<std::function<void()>>> pending_operations;
DelayedDestructionRing<TFence, 6> delayed_destruction_ring;
};
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 33431f2a0..28b38273e 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -14,10 +14,11 @@
#include "core/core.h"
#include "core/core_timing.h"
#include "core/frontend/emu_window.h"
-#include "core/hardware_interrupt_manager.h"
#include "core/hle/service/nvdrv/nvdata.h"
#include "core/perf_stats.h"
#include "video_core/cdma_pusher.h"
+#include "video_core/control/channel_state.h"
+#include "video_core/control/scheduler.h"
#include "video_core/dma_pusher.h"
#include "video_core/engines/fermi_2d.h"
#include "video_core/engines/kepler_compute.h"
@@ -26,75 +27,64 @@
#include "video_core/engines/maxwell_dma.h"
#include "video_core/gpu.h"
#include "video_core/gpu_thread.h"
+#include "video_core/host1x/host1x.h"
+#include "video_core/host1x/syncpoint_manager.h"
#include "video_core/memory_manager.h"
#include "video_core/renderer_base.h"
#include "video_core/shader_notify.h"
namespace Tegra {
-MICROPROFILE_DEFINE(GPU_wait, "GPU", "Wait for the GPU", MP_RGB(128, 128, 192));
-
struct GPU::Impl {
explicit Impl(GPU& gpu_, Core::System& system_, bool is_async_, bool use_nvdec_)
- : gpu{gpu_}, system{system_}, memory_manager{std::make_unique<Tegra::MemoryManager>(
- system)},
- dma_pusher{std::make_unique<Tegra::DmaPusher>(system, gpu)}, use_nvdec{use_nvdec_},
- maxwell_3d{std::make_unique<Engines::Maxwell3D>(system, *memory_manager)},
- fermi_2d{std::make_unique<Engines::Fermi2D>()},
- kepler_compute{std::make_unique<Engines::KeplerCompute>(system, *memory_manager)},
- maxwell_dma{std::make_unique<Engines::MaxwellDMA>(system, *memory_manager)},
- kepler_memory{std::make_unique<Engines::KeplerMemory>(system, *memory_manager)},
+ : gpu{gpu_}, system{system_}, host1x{system.Host1x()}, use_nvdec{use_nvdec_},
shader_notify{std::make_unique<VideoCore::ShaderNotify>()}, is_async{is_async_},
- gpu_thread{system_, is_async_} {}
+ gpu_thread{system_, is_async_}, scheduler{std::make_unique<Control::Scheduler>(gpu)} {}
~Impl() = default;
- /// Binds a renderer to the GPU.
- void BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer_) {
- renderer = std::move(renderer_);
- rasterizer = renderer->ReadRasterizer();
-
- memory_manager->BindRasterizer(rasterizer);
- maxwell_3d->BindRasterizer(rasterizer);
- fermi_2d->BindRasterizer(rasterizer);
- kepler_compute->BindRasterizer(rasterizer);
- kepler_memory->BindRasterizer(rasterizer);
- maxwell_dma->BindRasterizer(rasterizer);
+ std::shared_ptr<Control::ChannelState> CreateChannel(s32 channel_id) {
+ auto channel_state = std::make_shared<Tegra::Control::ChannelState>(channel_id);
+ channels.emplace(channel_id, channel_state);
+ scheduler->DeclareChannel(channel_state);
+ return channel_state;
}
- /// Calls a GPU method.
- void CallMethod(const GPU::MethodCall& method_call) {
- LOG_TRACE(HW_GPU, "Processing method {:08X} on subchannel {}", method_call.method,
- method_call.subchannel);
+ void BindChannel(s32 channel_id) {
+ if (bound_channel == channel_id) {
+ return;
+ }
+ auto it = channels.find(channel_id);
+ ASSERT(it != channels.end());
+ bound_channel = channel_id;
+ current_channel = it->second.get();
- ASSERT(method_call.subchannel < bound_engines.size());
+ rasterizer->BindChannel(*current_channel);
+ }
- if (ExecuteMethodOnEngine(method_call.method)) {
- CallEngineMethod(method_call);
- } else {
- CallPullerMethod(method_call);
- }
+ std::shared_ptr<Control::ChannelState> AllocateChannel() {
+ return CreateChannel(new_channel_id++);
}
- /// Calls a GPU multivalue method.
- void CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount,
- u32 methods_pending) {
- LOG_TRACE(HW_GPU, "Processing method {:08X} on subchannel {}", method, subchannel);
+ void InitChannel(Control::ChannelState& to_init) {
+ to_init.Init(system, gpu);
+ to_init.BindRasterizer(rasterizer);
+ rasterizer->InitializeChannel(to_init);
+ }
- ASSERT(subchannel < bound_engines.size());
+ void InitAddressSpace(Tegra::MemoryManager& memory_manager) {
+ memory_manager.BindRasterizer(rasterizer);
+ }
- if (ExecuteMethodOnEngine(method)) {
- CallEngineMultiMethod(method, subchannel, base_start, amount, methods_pending);
- } else {
- for (std::size_t i = 0; i < amount; i++) {
- CallPullerMethod(GPU::MethodCall{
- method,
- base_start[i],
- subchannel,
- methods_pending - static_cast<u32>(i),
- });
- }
- }
+ void ReleaseChannel(Control::ChannelState& to_release) {
+ UNIMPLEMENTED();
+ }
+
+ /// Binds a renderer to the GPU.
+ void BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer_) {
+ renderer = std::move(renderer_);
+ rasterizer = renderer->ReadRasterizer();
+ host1x.MemoryManager().BindRasterizer(rasterizer);
}
/// Flush all current written commands into the host GPU for execution.
@@ -103,85 +93,82 @@ struct GPU::Impl {
}
/// Synchronizes CPU writes with Host GPU memory.
- void SyncGuestHost() {
- rasterizer->SyncGuestHost();
+ void InvalidateGPUCache() {
+ rasterizer->InvalidateGPUCache();
}
/// Signal the ending of command list.
void OnCommandListEnd() {
- if (is_async) {
- // This command only applies to asynchronous GPU mode
- gpu_thread.OnCommandListEnd();
- }
+ gpu_thread.OnCommandListEnd();
}
/// Request a host GPU memory flush from the CPU.
- [[nodiscard]] u64 RequestFlush(VAddr addr, std::size_t size) {
- std::unique_lock lck{flush_request_mutex};
- const u64 fence = ++last_flush_fence;
- flush_requests.emplace_back(fence, addr, size);
+ template <typename Func>
+ [[nodiscard]] u64 RequestSyncOperation(Func&& action) {
+ std::unique_lock lck{sync_request_mutex};
+ const u64 fence = ++last_sync_fence;
+ sync_requests.emplace_back(action);
return fence;
}
/// Obtains current flush request fence id.
- [[nodiscard]] u64 CurrentFlushRequestFence() const {
- return current_flush_fence.load(std::memory_order_relaxed);
+ [[nodiscard]] u64 CurrentSyncRequestFence() const {
+ return current_sync_fence.load(std::memory_order_relaxed);
+ }
+
+ void WaitForSyncOperation(const u64 fence) {
+ std::unique_lock lck{sync_request_mutex};
+ sync_request_cv.wait(lck, [this, fence] { return CurrentSyncRequestFence() >= fence; });
}
/// Tick pending requests within the GPU.
void TickWork() {
- std::unique_lock lck{flush_request_mutex};
- while (!flush_requests.empty()) {
- auto& request = flush_requests.front();
- const u64 fence = request.fence;
- const VAddr addr = request.addr;
- const std::size_t size = request.size;
- flush_requests.pop_front();
- flush_request_mutex.unlock();
- rasterizer->FlushRegion(addr, size);
- current_flush_fence.store(fence);
- flush_request_mutex.lock();
+ std::unique_lock lck{sync_request_mutex};
+ while (!sync_requests.empty()) {
+ auto request = std::move(sync_requests.front());
+ sync_requests.pop_front();
+ sync_request_mutex.unlock();
+ request();
+ current_sync_fence.fetch_add(1, std::memory_order_release);
+ sync_request_mutex.lock();
+ sync_request_cv.notify_all();
}
}
/// Returns a reference to the Maxwell3D GPU engine.
[[nodiscard]] Engines::Maxwell3D& Maxwell3D() {
- return *maxwell_3d;
+ ASSERT(current_channel);
+ return *current_channel->maxwell_3d;
}
/// Returns a const reference to the Maxwell3D GPU engine.
[[nodiscard]] const Engines::Maxwell3D& Maxwell3D() const {
- return *maxwell_3d;
+ ASSERT(current_channel);
+ return *current_channel->maxwell_3d;
}
/// Returns a reference to the KeplerCompute GPU engine.
[[nodiscard]] Engines::KeplerCompute& KeplerCompute() {
- return *kepler_compute;
+ ASSERT(current_channel);
+ return *current_channel->kepler_compute;
}
/// Returns a reference to the KeplerCompute GPU engine.
[[nodiscard]] const Engines::KeplerCompute& KeplerCompute() const {
- return *kepler_compute;
- }
-
- /// Returns a reference to the GPU memory manager.
- [[nodiscard]] Tegra::MemoryManager& MemoryManager() {
- return *memory_manager;
- }
-
- /// Returns a const reference to the GPU memory manager.
- [[nodiscard]] const Tegra::MemoryManager& MemoryManager() const {
- return *memory_manager;
+ ASSERT(current_channel);
+ return *current_channel->kepler_compute;
}
/// Returns a reference to the GPU DMA pusher.
[[nodiscard]] Tegra::DmaPusher& DmaPusher() {
- return *dma_pusher;
+ ASSERT(current_channel);
+ return *current_channel->dma_pusher;
}
/// Returns a const reference to the GPU DMA pusher.
[[nodiscard]] const Tegra::DmaPusher& DmaPusher() const {
- return *dma_pusher;
+ ASSERT(current_channel);
+ return *current_channel->dma_pusher;
}
/// Returns a reference to the underlying renderer.
@@ -204,77 +191,6 @@ struct GPU::Impl {
return *shader_notify;
}
- /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame.
- void WaitFence(u32 syncpoint_id, u32 value) {
- // Synced GPU, is always in sync
- if (!is_async) {
- return;
- }
- if (syncpoint_id == UINT32_MAX) {
- // TODO: Research what this does.
- LOG_ERROR(HW_GPU, "Waiting for syncpoint -1 not implemented");
- return;
- }
- MICROPROFILE_SCOPE(GPU_wait);
- std::unique_lock lock{sync_mutex};
- sync_cv.wait(lock, [=, this] {
- if (shutting_down.load(std::memory_order_relaxed)) {
- // We're shutting down, ensure no threads continue to wait for the next syncpoint
- return true;
- }
- return syncpoints.at(syncpoint_id).load() >= value;
- });
- }
-
- void IncrementSyncPoint(u32 syncpoint_id) {
- auto& syncpoint = syncpoints.at(syncpoint_id);
- syncpoint++;
- std::scoped_lock lock{sync_mutex};
- sync_cv.notify_all();
- auto& interrupt = syncpt_interrupts.at(syncpoint_id);
- if (!interrupt.empty()) {
- u32 value = syncpoint.load();
- auto it = interrupt.begin();
- while (it != interrupt.end()) {
- if (value >= *it) {
- TriggerCpuInterrupt(syncpoint_id, *it);
- it = interrupt.erase(it);
- continue;
- }
- it++;
- }
- }
- }
-
- [[nodiscard]] u32 GetSyncpointValue(u32 syncpoint_id) const {
- return syncpoints.at(syncpoint_id).load();
- }
-
- void RegisterSyncptInterrupt(u32 syncpoint_id, u32 value) {
- std::scoped_lock lock{sync_mutex};
- auto& interrupt = syncpt_interrupts.at(syncpoint_id);
- bool contains = std::any_of(interrupt.begin(), interrupt.end(),
- [value](u32 in_value) { return in_value == value; });
- if (contains) {
- return;
- }
- interrupt.emplace_back(value);
- }
-
- [[nodiscard]] bool CancelSyncptInterrupt(u32 syncpoint_id, u32 value) {
- std::scoped_lock lock{sync_mutex};
- auto& interrupt = syncpt_interrupts.at(syncpoint_id);
- const auto iter =
- std::find_if(interrupt.begin(), interrupt.end(),
- [value](u32 interrupt_value) { return value == interrupt_value; });
-
- if (iter == interrupt.end()) {
- return false;
- }
- interrupt.erase(iter);
- return true;
- }
-
[[nodiscard]] u64 GetTicks() const {
// This values were reversed engineered by fincs from NVN
// The gpu clock is reported in units of 385/625 nanoseconds
@@ -306,7 +222,7 @@ struct GPU::Impl {
/// This can be used to launch any necessary threads and register any necessary
/// core timing events.
void Start() {
- gpu_thread.StartThread(*renderer, renderer->Context(), *dma_pusher);
+ gpu_thread.StartThread(*renderer, renderer->Context(), *scheduler);
cpu_context = renderer->GetRenderWindow().CreateSharedContext();
cpu_context->MakeCurrent();
}
@@ -328,8 +244,8 @@ struct GPU::Impl {
}
/// Push GPU command entries to be processed
- void PushGPUEntries(Tegra::CommandList&& entries) {
- gpu_thread.SubmitList(std::move(entries));
+ void PushGPUEntries(s32 channel, Tegra::CommandList&& entries) {
+ gpu_thread.SubmitList(channel, std::move(entries));
}
/// Push GPU command buffer entries to be processed
@@ -339,7 +255,7 @@ struct GPU::Impl {
}
if (!cdma_pushers.contains(id)) {
- cdma_pushers.insert_or_assign(id, std::make_unique<Tegra::CDmaPusher>(gpu));
+ cdma_pushers.insert_or_assign(id, std::make_unique<Tegra::CDmaPusher>(host1x));
}
// SubmitCommandBuffer would make the nvdec operations async, this is not currently working
@@ -376,308 +292,55 @@ struct GPU::Impl {
gpu_thread.FlushAndInvalidateRegion(addr, size);
}
- void TriggerCpuInterrupt(u32 syncpoint_id, u32 value) const {
- auto& interrupt_manager = system.InterruptManager();
- interrupt_manager.GPUInterruptSyncpt(syncpoint_id, value);
- }
-
- void ProcessBindMethod(const GPU::MethodCall& method_call) {
- // Bind the current subchannel to the desired engine id.
- LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", method_call.subchannel,
- method_call.argument);
- const auto engine_id = static_cast<EngineID>(method_call.argument);
- bound_engines[method_call.subchannel] = static_cast<EngineID>(engine_id);
- switch (engine_id) {
- case EngineID::FERMI_TWOD_A:
- dma_pusher->BindSubchannel(fermi_2d.get(), method_call.subchannel);
- break;
- case EngineID::MAXWELL_B:
- dma_pusher->BindSubchannel(maxwell_3d.get(), method_call.subchannel);
- break;
- case EngineID::KEPLER_COMPUTE_B:
- dma_pusher->BindSubchannel(kepler_compute.get(), method_call.subchannel);
- break;
- case EngineID::MAXWELL_DMA_COPY_A:
- dma_pusher->BindSubchannel(maxwell_dma.get(), method_call.subchannel);
- break;
- case EngineID::KEPLER_INLINE_TO_MEMORY_B:
- dma_pusher->BindSubchannel(kepler_memory.get(), method_call.subchannel);
- break;
- default:
- UNIMPLEMENTED_MSG("Unimplemented engine {:04X}", engine_id);
- }
- }
-
- void ProcessFenceActionMethod() {
- switch (regs.fence_action.op) {
- case GPU::FenceOperation::Acquire:
- WaitFence(regs.fence_action.syncpoint_id, regs.fence_value);
- break;
- case GPU::FenceOperation::Increment:
- IncrementSyncPoint(regs.fence_action.syncpoint_id);
- break;
- default:
- UNIMPLEMENTED_MSG("Unimplemented operation {}", regs.fence_action.op.Value());
- }
- }
-
- void ProcessWaitForInterruptMethod() {
- // TODO(bunnei) ImplementMe
- LOG_WARNING(HW_GPU, "(STUBBED) called");
- }
-
- void ProcessSemaphoreTriggerMethod() {
- const auto semaphoreOperationMask = 0xF;
- const auto op =
- static_cast<GpuSemaphoreOperation>(regs.semaphore_trigger & semaphoreOperationMask);
- if (op == GpuSemaphoreOperation::WriteLong) {
- struct Block {
- u32 sequence;
- u32 zeros = 0;
- u64 timestamp;
- };
-
- Block block{};
- block.sequence = regs.semaphore_sequence;
- // TODO(Kmather73): Generate a real GPU timestamp and write it here instead of
- // CoreTiming
- block.timestamp = GetTicks();
- memory_manager->WriteBlock(regs.semaphore_address.SemaphoreAddress(), &block,
- sizeof(block));
- } else {
- const u32 word{memory_manager->Read<u32>(regs.semaphore_address.SemaphoreAddress())};
- if ((op == GpuSemaphoreOperation::AcquireEqual && word == regs.semaphore_sequence) ||
- (op == GpuSemaphoreOperation::AcquireGequal &&
- static_cast<s32>(word - regs.semaphore_sequence) > 0) ||
- (op == GpuSemaphoreOperation::AcquireMask && (word & regs.semaphore_sequence))) {
- // Nothing to do in this case
+ void RequestSwapBuffers(const Tegra::FramebufferConfig* framebuffer,
+ std::array<Service::Nvidia::NvFence, 4>& fences, size_t num_fences) {
+ size_t current_request_counter{};
+ {
+ std::unique_lock<std::mutex> lk(request_swap_mutex);
+ if (free_swap_counters.empty()) {
+ current_request_counter = request_swap_counters.size();
+ request_swap_counters.emplace_back(num_fences);
} else {
- regs.acquire_source = true;
- regs.acquire_value = regs.semaphore_sequence;
- if (op == GpuSemaphoreOperation::AcquireEqual) {
- regs.acquire_active = true;
- regs.acquire_mode = false;
- } else if (op == GpuSemaphoreOperation::AcquireGequal) {
- regs.acquire_active = true;
- regs.acquire_mode = true;
- } else if (op == GpuSemaphoreOperation::AcquireMask) {
- // TODO(kemathe) The acquire mask operation waits for a value that, ANDed with
- // semaphore_sequence, gives a non-0 result
- LOG_ERROR(HW_GPU, "Invalid semaphore operation AcquireMask not implemented");
- } else {
- LOG_ERROR(HW_GPU, "Invalid semaphore operation");
- }
+ current_request_counter = free_swap_counters.front();
+ request_swap_counters[current_request_counter] = num_fences;
+ free_swap_counters.pop_front();
}
}
- }
-
- void ProcessSemaphoreRelease() {
- memory_manager->Write<u32>(regs.semaphore_address.SemaphoreAddress(),
- regs.semaphore_release);
- }
-
- void ProcessSemaphoreAcquire() {
- const u32 word = memory_manager->Read<u32>(regs.semaphore_address.SemaphoreAddress());
- const auto value = regs.semaphore_acquire;
- if (word != value) {
- regs.acquire_active = true;
- regs.acquire_value = value;
- // TODO(kemathe73) figure out how to do the acquire_timeout
- regs.acquire_mode = false;
- regs.acquire_source = false;
- }
- }
-
- /// Calls a GPU puller method.
- void CallPullerMethod(const GPU::MethodCall& method_call) {
- regs.reg_array[method_call.method] = method_call.argument;
- const auto method = static_cast<BufferMethods>(method_call.method);
-
- switch (method) {
- case BufferMethods::BindObject: {
- ProcessBindMethod(method_call);
- break;
- }
- case BufferMethods::Nop:
- case BufferMethods::SemaphoreAddressHigh:
- case BufferMethods::SemaphoreAddressLow:
- case BufferMethods::SemaphoreSequence:
- break;
- case BufferMethods::UnkCacheFlush:
- rasterizer->SyncGuestHost();
- break;
- case BufferMethods::WrcacheFlush:
- rasterizer->SignalReference();
- break;
- case BufferMethods::FenceValue:
- break;
- case BufferMethods::RefCnt:
- rasterizer->SignalReference();
- break;
- case BufferMethods::FenceAction:
- ProcessFenceActionMethod();
- break;
- case BufferMethods::WaitForInterrupt:
- rasterizer->WaitForIdle();
- break;
- case BufferMethods::SemaphoreTrigger: {
- ProcessSemaphoreTriggerMethod();
- break;
- }
- case BufferMethods::NotifyIntr: {
- // TODO(Kmather73): Research and implement this method.
- LOG_ERROR(HW_GPU, "Special puller engine method NotifyIntr not implemented");
- break;
- }
- case BufferMethods::Unk28: {
- // TODO(Kmather73): Research and implement this method.
- LOG_ERROR(HW_GPU, "Special puller engine method Unk28 not implemented");
- break;
- }
- case BufferMethods::SemaphoreAcquire: {
- ProcessSemaphoreAcquire();
- break;
- }
- case BufferMethods::SemaphoreRelease: {
- ProcessSemaphoreRelease();
- break;
- }
- case BufferMethods::Yield: {
- // TODO(Kmather73): Research and implement this method.
- LOG_ERROR(HW_GPU, "Special puller engine method Yield not implemented");
- break;
- }
- default:
- LOG_ERROR(HW_GPU, "Special puller engine method {:X} not implemented", method);
- break;
- }
- }
-
- /// Calls a GPU engine method.
- void CallEngineMethod(const GPU::MethodCall& method_call) {
- const EngineID engine = bound_engines[method_call.subchannel];
-
- switch (engine) {
- case EngineID::FERMI_TWOD_A:
- fermi_2d->CallMethod(method_call.method, method_call.argument,
- method_call.IsLastCall());
- break;
- case EngineID::MAXWELL_B:
- maxwell_3d->CallMethod(method_call.method, method_call.argument,
- method_call.IsLastCall());
- break;
- case EngineID::KEPLER_COMPUTE_B:
- kepler_compute->CallMethod(method_call.method, method_call.argument,
- method_call.IsLastCall());
- break;
- case EngineID::MAXWELL_DMA_COPY_A:
- maxwell_dma->CallMethod(method_call.method, method_call.argument,
- method_call.IsLastCall());
- break;
- case EngineID::KEPLER_INLINE_TO_MEMORY_B:
- kepler_memory->CallMethod(method_call.method, method_call.argument,
- method_call.IsLastCall());
- break;
- default:
- UNIMPLEMENTED_MSG("Unimplemented engine");
- }
- }
-
- /// Calls a GPU engine multivalue method.
- void CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount,
- u32 methods_pending) {
- const EngineID engine = bound_engines[subchannel];
-
- switch (engine) {
- case EngineID::FERMI_TWOD_A:
- fermi_2d->CallMultiMethod(method, base_start, amount, methods_pending);
- break;
- case EngineID::MAXWELL_B:
- maxwell_3d->CallMultiMethod(method, base_start, amount, methods_pending);
- break;
- case EngineID::KEPLER_COMPUTE_B:
- kepler_compute->CallMultiMethod(method, base_start, amount, methods_pending);
- break;
- case EngineID::MAXWELL_DMA_COPY_A:
- maxwell_dma->CallMultiMethod(method, base_start, amount, methods_pending);
- break;
- case EngineID::KEPLER_INLINE_TO_MEMORY_B:
- kepler_memory->CallMultiMethod(method, base_start, amount, methods_pending);
- break;
- default:
- UNIMPLEMENTED_MSG("Unimplemented engine");
- }
- }
-
- /// Determines where the method should be executed.
- [[nodiscard]] bool ExecuteMethodOnEngine(u32 method) {
- const auto buffer_method = static_cast<BufferMethods>(method);
- return buffer_method >= BufferMethods::NonPullerMethods;
- }
-
- struct Regs {
- static constexpr size_t NUM_REGS = 0x40;
-
- union {
- struct {
- INSERT_PADDING_WORDS_NOINIT(0x4);
- struct {
- u32 address_high;
- u32 address_low;
-
- [[nodiscard]] GPUVAddr SemaphoreAddress() const {
- return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
- address_low);
+ const auto wait_fence =
+ RequestSyncOperation([this, current_request_counter, framebuffer, fences, num_fences] {
+ auto& syncpoint_manager = host1x.GetSyncpointManager();
+ if (num_fences == 0) {
+ renderer->SwapBuffers(framebuffer);
+ }
+ const auto executer = [this, current_request_counter,
+ framebuffer_copy = *framebuffer]() {
+ {
+ std::unique_lock<std::mutex> lk(request_swap_mutex);
+ if (--request_swap_counters[current_request_counter] != 0) {
+ return;
+ }
+ free_swap_counters.push_back(current_request_counter);
}
- } semaphore_address;
-
- u32 semaphore_sequence;
- u32 semaphore_trigger;
- INSERT_PADDING_WORDS_NOINIT(0xC);
-
- // The pusher and the puller share the reference counter, the pusher only has read
- // access
- u32 reference_count;
- INSERT_PADDING_WORDS_NOINIT(0x5);
-
- u32 semaphore_acquire;
- u32 semaphore_release;
- u32 fence_value;
- GPU::FenceAction fence_action;
- INSERT_PADDING_WORDS_NOINIT(0xE2);
-
- // Puller state
- u32 acquire_mode;
- u32 acquire_source;
- u32 acquire_active;
- u32 acquire_timeout;
- u32 acquire_value;
- };
- std::array<u32, NUM_REGS> reg_array;
- };
- } regs{};
+ renderer->SwapBuffers(&framebuffer_copy);
+ };
+ for (size_t i = 0; i < num_fences; i++) {
+ syncpoint_manager.RegisterGuestAction(fences[i].id, fences[i].value, executer);
+ }
+ });
+ gpu_thread.TickGPU();
+ WaitForSyncOperation(wait_fence);
+ }
GPU& gpu;
Core::System& system;
- std::unique_ptr<Tegra::MemoryManager> memory_manager;
- std::unique_ptr<Tegra::DmaPusher> dma_pusher;
+ Host1x::Host1x& host1x;
+
std::map<u32, std::unique_ptr<Tegra::CDmaPusher>> cdma_pushers;
std::unique_ptr<VideoCore::RendererBase> renderer;
VideoCore::RasterizerInterface* rasterizer = nullptr;
const bool use_nvdec;
- /// Mapping of command subchannels to their bound engine ids
- std::array<EngineID, 8> bound_engines{};
- /// 3D engine
- std::unique_ptr<Engines::Maxwell3D> maxwell_3d;
- /// 2D engine
- std::unique_ptr<Engines::Fermi2D> fermi_2d;
- /// Compute engine
- std::unique_ptr<Engines::KeplerCompute> kepler_compute;
- /// DMA engine
- std::unique_ptr<Engines::MaxwellDMA> maxwell_dma;
- /// Inline memory engine
- std::unique_ptr<Engines::KeplerMemory> kepler_memory;
+ s32 new_channel_id{1};
/// Shader build notifier
std::unique_ptr<VideoCore::ShaderNotify> shader_notify;
/// When true, we are about to shut down emulation session, so terminate outstanding tasks
@@ -692,51 +355,25 @@ struct GPU::Impl {
std::condition_variable sync_cv;
- struct FlushRequest {
- explicit FlushRequest(u64 fence_, VAddr addr_, std::size_t size_)
- : fence{fence_}, addr{addr_}, size{size_} {}
- u64 fence;
- VAddr addr;
- std::size_t size;
- };
-
- std::list<FlushRequest> flush_requests;
- std::atomic<u64> current_flush_fence{};
- u64 last_flush_fence{};
- std::mutex flush_request_mutex;
+ std::list<std::function<void()>> sync_requests;
+ std::atomic<u64> current_sync_fence{};
+ u64 last_sync_fence{};
+ std::mutex sync_request_mutex;
+ std::condition_variable sync_request_cv;
const bool is_async;
VideoCommon::GPUThread::ThreadManager gpu_thread;
std::unique_ptr<Core::Frontend::GraphicsContext> cpu_context;
-#define ASSERT_REG_POSITION(field_name, position) \
- static_assert(offsetof(Regs, field_name) == position * 4, \
- "Field " #field_name " has invalid position")
-
- ASSERT_REG_POSITION(semaphore_address, 0x4);
- ASSERT_REG_POSITION(semaphore_sequence, 0x6);
- ASSERT_REG_POSITION(semaphore_trigger, 0x7);
- ASSERT_REG_POSITION(reference_count, 0x14);
- ASSERT_REG_POSITION(semaphore_acquire, 0x1A);
- ASSERT_REG_POSITION(semaphore_release, 0x1B);
- ASSERT_REG_POSITION(fence_value, 0x1C);
- ASSERT_REG_POSITION(fence_action, 0x1D);
-
- ASSERT_REG_POSITION(acquire_mode, 0x100);
- ASSERT_REG_POSITION(acquire_source, 0x101);
- ASSERT_REG_POSITION(acquire_active, 0x102);
- ASSERT_REG_POSITION(acquire_timeout, 0x103);
- ASSERT_REG_POSITION(acquire_value, 0x104);
-
-#undef ASSERT_REG_POSITION
-
- enum class GpuSemaphoreOperation {
- AcquireEqual = 0x1,
- WriteLong = 0x2,
- AcquireGequal = 0x4,
- AcquireMask = 0x8,
- };
+ std::unique_ptr<Tegra::Control::Scheduler> scheduler;
+ std::unordered_map<s32, std::shared_ptr<Tegra::Control::ChannelState>> channels;
+ Tegra::Control::ChannelState* current_channel;
+ s32 bound_channel{-1};
+
+ std::deque<size_t> free_swap_counters;
+ std::deque<size_t> request_swap_counters;
+ std::mutex request_swap_mutex;
};
GPU::GPU(Core::System& system, bool is_async, bool use_nvdec)
@@ -744,25 +381,36 @@ GPU::GPU(Core::System& system, bool is_async, bool use_nvdec)
GPU::~GPU() = default;
-void GPU::BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer) {
- impl->BindRenderer(std::move(renderer));
+std::shared_ptr<Control::ChannelState> GPU::AllocateChannel() {
+ return impl->AllocateChannel();
+}
+
+void GPU::InitChannel(Control::ChannelState& to_init) {
+ impl->InitChannel(to_init);
+}
+
+void GPU::BindChannel(s32 channel_id) {
+ impl->BindChannel(channel_id);
}
-void GPU::CallMethod(const MethodCall& method_call) {
- impl->CallMethod(method_call);
+void GPU::ReleaseChannel(Control::ChannelState& to_release) {
+ impl->ReleaseChannel(to_release);
}
-void GPU::CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount,
- u32 methods_pending) {
- impl->CallMultiMethod(method, subchannel, base_start, amount, methods_pending);
+void GPU::InitAddressSpace(Tegra::MemoryManager& memory_manager) {
+ impl->InitAddressSpace(memory_manager);
+}
+
+void GPU::BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer) {
+ impl->BindRenderer(std::move(renderer));
}
void GPU::FlushCommands() {
impl->FlushCommands();
}
-void GPU::SyncGuestHost() {
- impl->SyncGuestHost();
+void GPU::InvalidateGPUCache() {
+ impl->InvalidateGPUCache();
}
void GPU::OnCommandListEnd() {
@@ -770,17 +418,32 @@ void GPU::OnCommandListEnd() {
}
u64 GPU::RequestFlush(VAddr addr, std::size_t size) {
- return impl->RequestFlush(addr, size);
+ return impl->RequestSyncOperation(
+ [this, addr, size]() { impl->rasterizer->FlushRegion(addr, size); });
}
-u64 GPU::CurrentFlushRequestFence() const {
- return impl->CurrentFlushRequestFence();
+u64 GPU::CurrentSyncRequestFence() const {
+ return impl->CurrentSyncRequestFence();
+}
+
+void GPU::WaitForSyncOperation(u64 fence) {
+ return impl->WaitForSyncOperation(fence);
}
void GPU::TickWork() {
impl->TickWork();
}
+/// Gets a mutable reference to the Host1x interface
+Host1x::Host1x& GPU::Host1x() {
+ return impl->host1x;
+}
+
+/// Gets an immutable reference to the Host1x interface.
+const Host1x::Host1x& GPU::Host1x() const {
+ return impl->host1x;
+}
+
Engines::Maxwell3D& GPU::Maxwell3D() {
return impl->Maxwell3D();
}
@@ -797,14 +460,6 @@ const Engines::KeplerCompute& GPU::KeplerCompute() const {
return impl->KeplerCompute();
}
-Tegra::MemoryManager& GPU::MemoryManager() {
- return impl->MemoryManager();
-}
-
-const Tegra::MemoryManager& GPU::MemoryManager() const {
- return impl->MemoryManager();
-}
-
Tegra::DmaPusher& GPU::DmaPusher() {
return impl->DmaPusher();
}
@@ -829,24 +484,9 @@ const VideoCore::ShaderNotify& GPU::ShaderNotify() const {
return impl->ShaderNotify();
}
-void GPU::WaitFence(u32 syncpoint_id, u32 value) {
- impl->WaitFence(syncpoint_id, value);
-}
-
-void GPU::IncrementSyncPoint(u32 syncpoint_id) {
- impl->IncrementSyncPoint(syncpoint_id);
-}
-
-u32 GPU::GetSyncpointValue(u32 syncpoint_id) const {
- return impl->GetSyncpointValue(syncpoint_id);
-}
-
-void GPU::RegisterSyncptInterrupt(u32 syncpoint_id, u32 value) {
- impl->RegisterSyncptInterrupt(syncpoint_id, value);
-}
-
-bool GPU::CancelSyncptInterrupt(u32 syncpoint_id, u32 value) {
- return impl->CancelSyncptInterrupt(syncpoint_id, value);
+void GPU::RequestSwapBuffers(const Tegra::FramebufferConfig* framebuffer,
+ std::array<Service::Nvidia::NvFence, 4>& fences, size_t num_fences) {
+ impl->RequestSwapBuffers(framebuffer, fences, num_fences);
}
u64 GPU::GetTicks() const {
@@ -881,8 +521,8 @@ void GPU::ReleaseContext() {
impl->ReleaseContext();
}
-void GPU::PushGPUEntries(Tegra::CommandList&& entries) {
- impl->PushGPUEntries(std::move(entries));
+void GPU::PushGPUEntries(s32 channel, Tegra::CommandList&& entries) {
+ impl->PushGPUEntries(channel, std::move(entries));
}
void GPU::PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries) {
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index b939ba315..d0709dc69 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -24,11 +24,15 @@ namespace Tegra {
class DmaPusher;
struct CommandList;
+// TODO: Implement the commented ones
enum class RenderTargetFormat : u32 {
NONE = 0x0,
R32B32G32A32_FLOAT = 0xC0,
R32G32B32A32_SINT = 0xC1,
R32G32B32A32_UINT = 0xC2,
+ // R32G32B32X32_FLOAT = 0xC3,
+ // R32G32B32X32_SINT = 0xC4,
+ // R32G32B32X32_UINT = 0xC5,
R16G16B16A16_UNORM = 0xC6,
R16G16B16A16_SNORM = 0xC7,
R16G16B16A16_SINT = 0xC8,
@@ -38,8 +42,8 @@ enum class RenderTargetFormat : u32 {
R32G32_SINT = 0xCC,
R32G32_UINT = 0xCD,
R16G16B16X16_FLOAT = 0xCE,
- B8G8R8A8_UNORM = 0xCF,
- B8G8R8A8_SRGB = 0xD0,
+ A8R8G8B8_UNORM = 0xCF,
+ A8R8G8B8_SRGB = 0xD0,
A2B10G10R10_UNORM = 0xD1,
A2B10G10R10_UINT = 0xD2,
A8B8G8R8_UNORM = 0xD5,
@@ -52,10 +56,13 @@ enum class RenderTargetFormat : u32 {
R16G16_SINT = 0xDC,
R16G16_UINT = 0xDD,
R16G16_FLOAT = 0xDE,
+ // A2R10G10B10_UNORM = 0xDF,
B10G11R11_FLOAT = 0xE0,
R32_SINT = 0xE3,
R32_UINT = 0xE4,
R32_FLOAT = 0xE5,
+ // X8R8G8B8_UNORM = 0xE6,
+ // X8R8G8B8_SRGB = 0xE7,
R5G6B5_UNORM = 0xE8,
A1R5G5B5_UNORM = 0xE9,
R8G8_UNORM = 0xEA,
@@ -71,17 +78,42 @@ enum class RenderTargetFormat : u32 {
R8_SNORM = 0xF4,
R8_SINT = 0xF5,
R8_UINT = 0xF6,
+
+ /*
+ A8_UNORM = 0xF7,
+ X1R5G5B5_UNORM = 0xF8,
+ X8B8G8R8_UNORM = 0xF9,
+ X8B8G8R8_SRGB = 0xFA,
+ Z1R5G5B5_UNORM = 0xFB,
+ O1R5G5B5_UNORM = 0xFC,
+ Z8R8G8B8_UNORM = 0xFD,
+ O8R8G8B8_UNORM = 0xFE,
+ R32_UNORM = 0xFF,
+ A16_UNORM = 0x40,
+ A16_FLOAT = 0x41,
+ A32_FLOAT = 0x42,
+ A8R8_UNORM = 0x43,
+ R16A16_UNORM = 0x44,
+ R16A16_FLOAT = 0x45,
+ R32A32_FLOAT = 0x46,
+ B8G8R8A8_UNORM = 0x47,
+ */
};
enum class DepthFormat : u32 {
- D32_FLOAT = 0xA,
- D16_UNORM = 0x13,
- S8_UINT_Z24_UNORM = 0x14,
- D24X8_UNORM = 0x15,
- D24S8_UNORM = 0x16,
+ Z32_FLOAT = 0xA,
+ Z16_UNORM = 0x13,
+ Z24_UNORM_S8_UINT = 0x14,
+ X8Z24_UNORM = 0x15,
+ S8Z24_UNORM = 0x16,
S8_UINT = 0x17,
- D24C8_UNORM = 0x18,
- D32_FLOAT_S8X24_UINT = 0x19,
+ V8Z24_UNORM = 0x18,
+ Z32_FLOAT_X24S8_UINT = 0x19,
+ /*
+ X8Z24_UNORM_X16V8S8_UINT = 0x1D,
+ Z32_FLOAT_X16V8X8_UINT = 0x1E,
+ Z32_FLOAT_X16V8S8_UINT = 0x1F,
+ */
};
namespace Engines {
@@ -89,73 +121,58 @@ class Maxwell3D;
class KeplerCompute;
} // namespace Engines
-enum class EngineID {
- FERMI_TWOD_A = 0x902D, // 2D Engine
- MAXWELL_B = 0xB197, // 3D Engine
- KEPLER_COMPUTE_B = 0xB1C0,
- KEPLER_INLINE_TO_MEMORY_B = 0xA140,
- MAXWELL_DMA_COPY_A = 0xB0B5,
-};
+namespace Control {
+struct ChannelState;
+}
+
+namespace Host1x {
+class Host1x;
+} // namespace Host1x
class MemoryManager;
class GPU final {
public:
- struct MethodCall {
- u32 method{};
- u32 argument{};
- u32 subchannel{};
- u32 method_count{};
-
- explicit MethodCall(u32 method_, u32 argument_, u32 subchannel_ = 0, u32 method_count_ = 0)
- : method(method_), argument(argument_), subchannel(subchannel_),
- method_count(method_count_) {}
-
- [[nodiscard]] bool IsLastCall() const {
- return method_count <= 1;
- }
- };
-
- enum class FenceOperation : u32 {
- Acquire = 0,
- Increment = 1,
- };
-
- union FenceAction {
- u32 raw;
- BitField<0, 1, FenceOperation> op;
- BitField<8, 24, u32> syncpoint_id;
- };
-
explicit GPU(Core::System& system, bool is_async, bool use_nvdec);
~GPU();
/// Binds a renderer to the GPU.
void BindRenderer(std::unique_ptr<VideoCore::RendererBase> renderer);
- /// Calls a GPU method.
- void CallMethod(const MethodCall& method_call);
-
- /// Calls a GPU multivalue method.
- void CallMultiMethod(u32 method, u32 subchannel, const u32* base_start, u32 amount,
- u32 methods_pending);
-
/// Flush all current written commands into the host GPU for execution.
void FlushCommands();
/// Synchronizes CPU writes with Host GPU memory.
- void SyncGuestHost();
+ void InvalidateGPUCache();
/// Signal the ending of command list.
void OnCommandListEnd();
+ std::shared_ptr<Control::ChannelState> AllocateChannel();
+
+ void InitChannel(Control::ChannelState& to_init);
+
+ void BindChannel(s32 channel_id);
+
+ void ReleaseChannel(Control::ChannelState& to_release);
+
+ void InitAddressSpace(Tegra::MemoryManager& memory_manager);
+
/// Request a host GPU memory flush from the CPU.
[[nodiscard]] u64 RequestFlush(VAddr addr, std::size_t size);
/// Obtains current flush request fence id.
- [[nodiscard]] u64 CurrentFlushRequestFence() const;
+ [[nodiscard]] u64 CurrentSyncRequestFence() const;
+
+ void WaitForSyncOperation(u64 fence);
/// Tick pending requests within the GPU.
void TickWork();
+ /// Gets a mutable reference to the Host1x interface
+ [[nodiscard]] Host1x::Host1x& Host1x();
+
+ /// Gets an immutable reference to the Host1x interface.
+ [[nodiscard]] const Host1x::Host1x& Host1x() const;
+
/// Returns a reference to the Maxwell3D GPU engine.
[[nodiscard]] Engines::Maxwell3D& Maxwell3D();
@@ -168,12 +185,6 @@ public:
/// Returns a reference to the KeplerCompute GPU engine.
[[nodiscard]] const Engines::KeplerCompute& KeplerCompute() const;
- /// Returns a reference to the GPU memory manager.
- [[nodiscard]] Tegra::MemoryManager& MemoryManager();
-
- /// Returns a const reference to the GPU memory manager.
- [[nodiscard]] const Tegra::MemoryManager& MemoryManager() const;
-
/// Returns a reference to the GPU DMA pusher.
[[nodiscard]] Tegra::DmaPusher& DmaPusher();
@@ -192,17 +203,6 @@ public:
/// Returns a const reference to the shader notifier.
[[nodiscard]] const VideoCore::ShaderNotify& ShaderNotify() const;
- /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame.
- void WaitFence(u32 syncpoint_id, u32 value);
-
- void IncrementSyncPoint(u32 syncpoint_id);
-
- [[nodiscard]] u32 GetSyncpointValue(u32 syncpoint_id) const;
-
- void RegisterSyncptInterrupt(u32 syncpoint_id, u32 value);
-
- [[nodiscard]] bool CancelSyncptInterrupt(u32 syncpoint_id, u32 value);
-
[[nodiscard]] u64 GetTicks() const;
[[nodiscard]] bool IsAsync() const;
@@ -211,6 +211,9 @@ public:
void RendererFrameEndNotify();
+ void RequestSwapBuffers(const Tegra::FramebufferConfig* framebuffer,
+ std::array<Service::Nvidia::NvFence, 4>& fences, size_t num_fences);
+
/// Performs any additional setup necessary in order to begin GPU emulation.
/// This can be used to launch any necessary threads and register any necessary
/// core timing events.
@@ -226,7 +229,7 @@ public:
void ReleaseContext();
/// Push GPU command entries to be processed
- void PushGPUEntries(Tegra::CommandList&& entries);
+ void PushGPUEntries(s32 channel, Tegra::CommandList&& entries);
/// Push GPU command buffer entries to be processed
void PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries);
@@ -248,7 +251,7 @@ public:
private:
struct Impl;
- std::unique_ptr<Impl> impl;
+ mutable std::unique_ptr<Impl> impl;
};
} // namespace Tegra
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index d43f7175a..1bd477011 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -8,6 +8,7 @@
#include "common/thread.h"
#include "core/core.h"
#include "core/frontend/emu_window.h"
+#include "video_core/control/scheduler.h"
#include "video_core/dma_pusher.h"
#include "video_core/gpu.h"
#include "video_core/gpu_thread.h"
@@ -18,8 +19,8 @@ namespace VideoCommon::GPUThread {
/// Runs the GPU thread
static void RunThread(std::stop_token stop_token, Core::System& system,
VideoCore::RendererBase& renderer, Core::Frontend::GraphicsContext& context,
- Tegra::DmaPusher& dma_pusher, SynchState& state) {
- std::string name = "yuzu:GPU";
+ Tegra::Control::Scheduler& scheduler, SynchState& state) {
+ std::string name = "GPU";
MicroProfileOnThreadCreate(name.c_str());
SCOPE_EXIT({ MicroProfileOnThreadExit(); });
@@ -36,8 +37,7 @@ static void RunThread(std::stop_token stop_token, Core::System& system,
break;
}
if (auto* submit_list = std::get_if<SubmitListCommand>(&next.data)) {
- dma_pusher.Push(std::move(submit_list->entries));
- dma_pusher.DispatchCalls();
+ scheduler.Push(submit_list->channel, std::move(submit_list->entries));
} else if (const auto* data = std::get_if<SwapBuffersCommand>(&next.data)) {
renderer.SwapBuffers(data->framebuffer ? &*data->framebuffer : nullptr);
} else if (std::holds_alternative<OnCommandListEndCommand>(next.data)) {
@@ -68,14 +68,14 @@ ThreadManager::~ThreadManager() = default;
void ThreadManager::StartThread(VideoCore::RendererBase& renderer,
Core::Frontend::GraphicsContext& context,
- Tegra::DmaPusher& dma_pusher) {
+ Tegra::Control::Scheduler& scheduler) {
rasterizer = renderer.ReadRasterizer();
thread = std::jthread(RunThread, std::ref(system), std::ref(renderer), std::ref(context),
- std::ref(dma_pusher), std::ref(state));
+ std::ref(scheduler), std::ref(state));
}
-void ThreadManager::SubmitList(Tegra::CommandList&& entries) {
- PushCommand(SubmitListCommand(std::move(entries)));
+void ThreadManager::SubmitList(s32 channel, Tegra::CommandList&& entries) {
+ PushCommand(SubmitListCommand(channel, std::move(entries)));
}
void ThreadManager::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
@@ -93,8 +93,12 @@ void ThreadManager::FlushRegion(VAddr addr, u64 size) {
}
auto& gpu = system.GPU();
u64 fence = gpu.RequestFlush(addr, size);
- PushCommand(GPUTickCommand(), true);
- ASSERT(fence <= gpu.CurrentFlushRequestFence());
+ TickGPU();
+ gpu.WaitForSyncOperation(fence);
+}
+
+void ThreadManager::TickGPU() {
+ PushCommand(GPUTickCommand());
}
void ThreadManager::InvalidateRegion(VAddr addr, u64 size) {
diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h
index 2f8210cb9..64628d3e3 100644
--- a/src/video_core/gpu_thread.h
+++ b/src/video_core/gpu_thread.h
@@ -15,7 +15,9 @@
namespace Tegra {
struct FramebufferConfig;
-class DmaPusher;
+namespace Control {
+class Scheduler;
+}
} // namespace Tegra
namespace Core {
@@ -34,8 +36,10 @@ namespace VideoCommon::GPUThread {
/// Command to signal to the GPU thread that a command list is ready for processing
struct SubmitListCommand final {
- explicit SubmitListCommand(Tegra::CommandList&& entries_) : entries{std::move(entries_)} {}
+ explicit SubmitListCommand(s32 channel_, Tegra::CommandList&& entries_)
+ : channel{channel_}, entries{std::move(entries_)} {}
+ s32 channel;
Tegra::CommandList entries;
};
@@ -112,10 +116,10 @@ public:
/// Creates and starts the GPU thread.
void StartThread(VideoCore::RendererBase& renderer, Core::Frontend::GraphicsContext& context,
- Tegra::DmaPusher& dma_pusher);
+ Tegra::Control::Scheduler& scheduler);
/// Push GPU command entries to be processed
- void SubmitList(Tegra::CommandList&& entries);
+ void SubmitList(s32 channel, Tegra::CommandList&& entries);
/// Swap buffers (render frame)
void SwapBuffers(const Tegra::FramebufferConfig* framebuffer);
@@ -131,6 +135,8 @@ public:
void OnCommandListEnd();
+ void TickGPU();
+
private:
/// Pushes a command to be executed by the GPU thread
u64 PushCommand(CommandData&& command_data, bool block = false);
diff --git a/src/video_core/command_classes/codecs/codec.cpp b/src/video_core/host1x/codecs/codec.cpp
index a5eb97b7f..42e7d6e4f 100644
--- a/src/video_core/command_classes/codecs/codec.cpp
+++ b/src/video_core/host1x/codecs/codec.cpp
@@ -6,11 +6,11 @@
#include <vector>
#include "common/assert.h"
#include "common/settings.h"
-#include "video_core/command_classes/codecs/codec.h"
-#include "video_core/command_classes/codecs/h264.h"
-#include "video_core/command_classes/codecs/vp8.h"
-#include "video_core/command_classes/codecs/vp9.h"
-#include "video_core/gpu.h"
+#include "video_core/host1x/codecs/codec.h"
+#include "video_core/host1x/codecs/h264.h"
+#include "video_core/host1x/codecs/vp8.h"
+#include "video_core/host1x/codecs/vp9.h"
+#include "video_core/host1x/host1x.h"
#include "video_core/memory_manager.h"
extern "C" {
@@ -73,10 +73,10 @@ void AVFrameDeleter(AVFrame* ptr) {
av_frame_free(&ptr);
}
-Codec::Codec(GPU& gpu_, const NvdecCommon::NvdecRegisters& regs)
- : gpu(gpu_), state{regs}, h264_decoder(std::make_unique<Decoder::H264>(gpu)),
- vp8_decoder(std::make_unique<Decoder::VP8>(gpu)),
- vp9_decoder(std::make_unique<Decoder::VP9>(gpu)) {}
+Codec::Codec(Host1x::Host1x& host1x_, const Host1x::NvdecCommon::NvdecRegisters& regs)
+ : host1x(host1x_), state{regs}, h264_decoder(std::make_unique<Decoder::H264>(host1x)),
+ vp8_decoder(std::make_unique<Decoder::VP8>(host1x)),
+ vp9_decoder(std::make_unique<Decoder::VP9>(host1x)) {}
Codec::~Codec() {
if (!initialized) {
@@ -168,11 +168,11 @@ void Codec::InitializeGpuDecoder() {
void Codec::Initialize() {
const AVCodecID codec = [&] {
switch (current_codec) {
- case NvdecCommon::VideoCodec::H264:
+ case Host1x::NvdecCommon::VideoCodec::H264:
return AV_CODEC_ID_H264;
- case NvdecCommon::VideoCodec::VP8:
+ case Host1x::NvdecCommon::VideoCodec::VP8:
return AV_CODEC_ID_VP8;
- case NvdecCommon::VideoCodec::VP9:
+ case Host1x::NvdecCommon::VideoCodec::VP9:
return AV_CODEC_ID_VP9;
default:
UNIMPLEMENTED_MSG("Unknown codec {}", current_codec);
@@ -197,7 +197,7 @@ void Codec::Initialize() {
initialized = true;
}
-void Codec::SetTargetCodec(NvdecCommon::VideoCodec codec) {
+void Codec::SetTargetCodec(Host1x::NvdecCommon::VideoCodec codec) {
if (current_codec != codec) {
current_codec = codec;
LOG_INFO(Service_NVDRV, "NVDEC video codec initialized to {}", GetCurrentCodecName());
@@ -215,11 +215,11 @@ void Codec::Decode() {
bool vp9_hidden_frame = false;
const auto& frame_data = [&]() {
switch (current_codec) {
- case Tegra::NvdecCommon::VideoCodec::H264:
+ case Tegra::Host1x::NvdecCommon::VideoCodec::H264:
return h264_decoder->ComposeFrame(state, is_first_frame);
- case Tegra::NvdecCommon::VideoCodec::VP8:
+ case Tegra::Host1x::NvdecCommon::VideoCodec::VP8:
return vp8_decoder->ComposeFrame(state);
- case Tegra::NvdecCommon::VideoCodec::VP9:
+ case Tegra::Host1x::NvdecCommon::VideoCodec::VP9:
vp9_decoder->ComposeFrame(state);
vp9_hidden_frame = vp9_decoder->WasFrameHidden();
return vp9_decoder->GetFrameBytes();
@@ -287,21 +287,21 @@ AVFramePtr Codec::GetCurrentFrame() {
return frame;
}
-NvdecCommon::VideoCodec Codec::GetCurrentCodec() const {
+Host1x::NvdecCommon::VideoCodec Codec::GetCurrentCodec() const {
return current_codec;
}
std::string_view Codec::GetCurrentCodecName() const {
switch (current_codec) {
- case NvdecCommon::VideoCodec::None:
+ case Host1x::NvdecCommon::VideoCodec::None:
return "None";
- case NvdecCommon::VideoCodec::H264:
+ case Host1x::NvdecCommon::VideoCodec::H264:
return "H264";
- case NvdecCommon::VideoCodec::VP8:
+ case Host1x::NvdecCommon::VideoCodec::VP8:
return "VP8";
- case NvdecCommon::VideoCodec::H265:
+ case Host1x::NvdecCommon::VideoCodec::H265:
return "H265";
- case NvdecCommon::VideoCodec::VP9:
+ case Host1x::NvdecCommon::VideoCodec::VP9:
return "VP9";
default:
return "Unknown";
diff --git a/src/video_core/command_classes/codecs/codec.h b/src/video_core/host1x/codecs/codec.h
index 0c2405465..0d45fb7fe 100644
--- a/src/video_core/command_classes/codecs/codec.h
+++ b/src/video_core/host1x/codecs/codec.h
@@ -6,8 +6,8 @@
#include <memory>
#include <string_view>
#include <queue>
-
-#include "video_core/command_classes/nvdec_common.h"
+#include "common/common_types.h"
+#include "video_core/host1x/nvdec_common.h"
extern "C" {
#if defined(__GNUC__) || defined(__clang__)
@@ -21,7 +21,6 @@ extern "C" {
}
namespace Tegra {
-class GPU;
void AVFrameDeleter(AVFrame* ptr);
using AVFramePtr = std::unique_ptr<AVFrame, decltype(&AVFrameDeleter)>;
@@ -32,16 +31,20 @@ class VP8;
class VP9;
} // namespace Decoder
+namespace Host1x {
+class Host1x;
+} // namespace Host1x
+
class Codec {
public:
- explicit Codec(GPU& gpu, const NvdecCommon::NvdecRegisters& regs);
+ explicit Codec(Host1x::Host1x& host1x, const Host1x::NvdecCommon::NvdecRegisters& regs);
~Codec();
/// Initialize the codec, returning success or failure
void Initialize();
/// Sets NVDEC video stream codec
- void SetTargetCodec(NvdecCommon::VideoCodec codec);
+ void SetTargetCodec(Host1x::NvdecCommon::VideoCodec codec);
/// Call decoders to construct headers, decode AVFrame with ffmpeg
void Decode();
@@ -50,7 +53,7 @@ public:
[[nodiscard]] AVFramePtr GetCurrentFrame();
/// Returns the value of current_codec
- [[nodiscard]] NvdecCommon::VideoCodec GetCurrentCodec() const;
+ [[nodiscard]] Host1x::NvdecCommon::VideoCodec GetCurrentCodec() const;
/// Return name of the current codec
[[nodiscard]] std::string_view GetCurrentCodecName() const;
@@ -63,14 +66,14 @@ private:
bool CreateGpuAvDevice();
bool initialized{};
- NvdecCommon::VideoCodec current_codec{NvdecCommon::VideoCodec::None};
+ Host1x::NvdecCommon::VideoCodec current_codec{Host1x::NvdecCommon::VideoCodec::None};
const AVCodec* av_codec{nullptr};
AVCodecContext* av_codec_ctx{nullptr};
AVBufferRef* av_gpu_decoder{nullptr};
- GPU& gpu;
- const NvdecCommon::NvdecRegisters& state;
+ Host1x::Host1x& host1x;
+ const Host1x::NvdecCommon::NvdecRegisters& state;
std::unique_ptr<Decoder::H264> h264_decoder;
std::unique_ptr<Decoder::VP8> vp8_decoder;
std::unique_ptr<Decoder::VP9> vp9_decoder;
diff --git a/src/video_core/command_classes/codecs/h264.cpp b/src/video_core/host1x/codecs/h264.cpp
index e2acd54d4..e87bd65fa 100644
--- a/src/video_core/command_classes/codecs/h264.cpp
+++ b/src/video_core/host1x/codecs/h264.cpp
@@ -5,8 +5,8 @@
#include <bit>
#include "common/settings.h"
-#include "video_core/command_classes/codecs/h264.h"
-#include "video_core/gpu.h"
+#include "video_core/host1x/codecs/h264.h"
+#include "video_core/host1x/host1x.h"
#include "video_core/memory_manager.h"
namespace Tegra::Decoder {
@@ -24,19 +24,20 @@ constexpr std::array<u8, 16> zig_zag_scan{
};
} // Anonymous namespace
-H264::H264(GPU& gpu_) : gpu(gpu_) {}
+H264::H264(Host1x::Host1x& host1x_) : host1x{host1x_} {}
H264::~H264() = default;
-const std::vector<u8>& H264::ComposeFrame(const NvdecCommon::NvdecRegisters& state,
+const std::vector<u8>& H264::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state,
bool is_first_frame) {
H264DecoderContext context;
- gpu.MemoryManager().ReadBlock(state.picture_info_offset, &context, sizeof(H264DecoderContext));
+ host1x.MemoryManager().ReadBlock(state.picture_info_offset, &context,
+ sizeof(H264DecoderContext));
const s64 frame_number = context.h264_parameter_set.frame_number.Value();
if (!is_first_frame && frame_number != 0) {
frame.resize(context.stream_len);
- gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.data(), frame.size());
+ host1x.MemoryManager().ReadBlock(state.frame_bitstream_offset, frame.data(), frame.size());
return frame;
}
@@ -155,8 +156,8 @@ const std::vector<u8>& H264::ComposeFrame(const NvdecCommon::NvdecRegisters& sta
frame.resize(encoded_header.size() + context.stream_len);
std::memcpy(frame.data(), encoded_header.data(), encoded_header.size());
- gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset,
- frame.data() + encoded_header.size(), context.stream_len);
+ host1x.MemoryManager().ReadBlock(state.frame_bitstream_offset,
+ frame.data() + encoded_header.size(), context.stream_len);
return frame;
}
diff --git a/src/video_core/command_classes/codecs/h264.h b/src/video_core/host1x/codecs/h264.h
index 261574364..5cc86454e 100644
--- a/src/video_core/command_classes/codecs/h264.h
+++ b/src/video_core/host1x/codecs/h264.h
@@ -8,10 +8,14 @@
#include "common/bit_field.h"
#include "common/common_funcs.h"
#include "common/common_types.h"
-#include "video_core/command_classes/nvdec_common.h"
+#include "video_core/host1x/nvdec_common.h"
namespace Tegra {
-class GPU;
+
+namespace Host1x {
+class Host1x;
+} // namespace Host1x
+
namespace Decoder {
class H264BitWriter {
@@ -55,16 +59,16 @@ private:
class H264 {
public:
- explicit H264(GPU& gpu);
+ explicit H264(Host1x::Host1x& host1x);
~H264();
/// Compose the H264 frame for FFmpeg decoding
- [[nodiscard]] const std::vector<u8>& ComposeFrame(const NvdecCommon::NvdecRegisters& state,
- bool is_first_frame = false);
+ [[nodiscard]] const std::vector<u8>& ComposeFrame(
+ const Host1x::NvdecCommon::NvdecRegisters& state, bool is_first_frame = false);
private:
std::vector<u8> frame;
- GPU& gpu;
+ Host1x::Host1x& host1x;
struct H264ParameterSet {
s32 log2_max_pic_order_cnt_lsb_minus4; ///< 0x00
diff --git a/src/video_core/command_classes/codecs/vp8.cpp b/src/video_core/host1x/codecs/vp8.cpp
index c83b9bbc2..28fb12cb8 100644
--- a/src/video_core/command_classes/codecs/vp8.cpp
+++ b/src/video_core/host1x/codecs/vp8.cpp
@@ -3,18 +3,18 @@
#include <vector>
-#include "video_core/command_classes/codecs/vp8.h"
-#include "video_core/gpu.h"
+#include "video_core/host1x/codecs/vp8.h"
+#include "video_core/host1x/host1x.h"
#include "video_core/memory_manager.h"
namespace Tegra::Decoder {
-VP8::VP8(GPU& gpu_) : gpu(gpu_) {}
+VP8::VP8(Host1x::Host1x& host1x_) : host1x{host1x_} {}
VP8::~VP8() = default;
-const std::vector<u8>& VP8::ComposeFrame(const NvdecCommon::NvdecRegisters& state) {
+const std::vector<u8>& VP8::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state) {
VP8PictureInfo info;
- gpu.MemoryManager().ReadBlock(state.picture_info_offset, &info, sizeof(VP8PictureInfo));
+ host1x.MemoryManager().ReadBlock(state.picture_info_offset, &info, sizeof(VP8PictureInfo));
const bool is_key_frame = info.key_frame == 1u;
const auto bitstream_size = static_cast<size_t>(info.vld_buffer_size);
@@ -45,7 +45,7 @@ const std::vector<u8>& VP8::ComposeFrame(const NvdecCommon::NvdecRegisters& stat
frame[9] = static_cast<u8>(((info.frame_height >> 8) & 0x3f));
}
const u64 bitstream_offset = state.frame_bitstream_offset;
- gpu.MemoryManager().ReadBlock(bitstream_offset, frame.data() + header_size, bitstream_size);
+ host1x.MemoryManager().ReadBlock(bitstream_offset, frame.data() + header_size, bitstream_size);
return frame;
}
diff --git a/src/video_core/command_classes/codecs/vp8.h b/src/video_core/host1x/codecs/vp8.h
index 3357667b0..5bf07ecab 100644
--- a/src/video_core/command_classes/codecs/vp8.h
+++ b/src/video_core/host1x/codecs/vp8.h
@@ -8,23 +8,28 @@
#include "common/common_funcs.h"
#include "common/common_types.h"
-#include "video_core/command_classes/nvdec_common.h"
+#include "video_core/host1x/nvdec_common.h"
namespace Tegra {
-class GPU;
+
+namespace Host1x {
+class Host1x;
+} // namespace Host1x
+
namespace Decoder {
class VP8 {
public:
- explicit VP8(GPU& gpu);
+ explicit VP8(Host1x::Host1x& host1x);
~VP8();
/// Compose the VP8 frame for FFmpeg decoding
- [[nodiscard]] const std::vector<u8>& ComposeFrame(const NvdecCommon::NvdecRegisters& state);
+ [[nodiscard]] const std::vector<u8>& ComposeFrame(
+ const Host1x::NvdecCommon::NvdecRegisters& state);
private:
std::vector<u8> frame;
- GPU& gpu;
+ Host1x::Host1x& host1x;
struct VP8PictureInfo {
INSERT_PADDING_WORDS_NOINIT(14);
diff --git a/src/video_core/command_classes/codecs/vp9.cpp b/src/video_core/host1x/codecs/vp9.cpp
index c01431441..cf40c9012 100644
--- a/src/video_core/command_classes/codecs/vp9.cpp
+++ b/src/video_core/host1x/codecs/vp9.cpp
@@ -4,8 +4,8 @@
#include <algorithm> // for std::copy
#include <numeric>
#include "common/assert.h"
-#include "video_core/command_classes/codecs/vp9.h"
-#include "video_core/gpu.h"
+#include "video_core/host1x/codecs/vp9.h"
+#include "video_core/host1x/host1x.h"
#include "video_core/memory_manager.h"
namespace Tegra::Decoder {
@@ -236,7 +236,7 @@ constexpr std::array<u8, 254> map_lut{
}
} // Anonymous namespace
-VP9::VP9(GPU& gpu_) : gpu{gpu_} {}
+VP9::VP9(Host1x::Host1x& host1x_) : host1x{host1x_} {}
VP9::~VP9() = default;
@@ -355,9 +355,9 @@ void VP9::WriteMvProbabilityUpdate(VpxRangeEncoder& writer, u8 new_prob, u8 old_
}
}
-Vp9PictureInfo VP9::GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state) {
+Vp9PictureInfo VP9::GetVp9PictureInfo(const Host1x::NvdecCommon::NvdecRegisters& state) {
PictureInfo picture_info;
- gpu.MemoryManager().ReadBlock(state.picture_info_offset, &picture_info, sizeof(PictureInfo));
+ host1x.MemoryManager().ReadBlock(state.picture_info_offset, &picture_info, sizeof(PictureInfo));
Vp9PictureInfo vp9_info = picture_info.Convert();
InsertEntropy(state.vp9_entropy_probs_offset, vp9_info.entropy);
@@ -372,18 +372,19 @@ Vp9PictureInfo VP9::GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state)
void VP9::InsertEntropy(u64 offset, Vp9EntropyProbs& dst) {
EntropyProbs entropy;
- gpu.MemoryManager().ReadBlock(offset, &entropy, sizeof(EntropyProbs));
+ host1x.MemoryManager().ReadBlock(offset, &entropy, sizeof(EntropyProbs));
entropy.Convert(dst);
}
-Vp9FrameContainer VP9::GetCurrentFrame(const NvdecCommon::NvdecRegisters& state) {
+Vp9FrameContainer VP9::GetCurrentFrame(const Host1x::NvdecCommon::NvdecRegisters& state) {
Vp9FrameContainer current_frame{};
{
- gpu.SyncGuestHost();
+ // gpu.SyncGuestHost(); epic, why?
current_frame.info = GetVp9PictureInfo(state);
current_frame.bit_stream.resize(current_frame.info.bitstream_size);
- gpu.MemoryManager().ReadBlock(state.frame_bitstream_offset, current_frame.bit_stream.data(),
- current_frame.info.bitstream_size);
+ host1x.MemoryManager().ReadBlock(state.frame_bitstream_offset,
+ current_frame.bit_stream.data(),
+ current_frame.info.bitstream_size);
}
if (!next_frame.bit_stream.empty()) {
Vp9FrameContainer temp{
@@ -769,7 +770,7 @@ VpxBitStreamWriter VP9::ComposeUncompressedHeader() {
return uncomp_writer;
}
-void VP9::ComposeFrame(const NvdecCommon::NvdecRegisters& state) {
+void VP9::ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state) {
std::vector<u8> bitstream;
{
Vp9FrameContainer curr_frame = GetCurrentFrame(state);
diff --git a/src/video_core/command_classes/codecs/vp9.h b/src/video_core/host1x/codecs/vp9.h
index ecc40e8b1..d4083e8d3 100644
--- a/src/video_core/command_classes/codecs/vp9.h
+++ b/src/video_core/host1x/codecs/vp9.h
@@ -8,11 +8,15 @@
#include "common/common_types.h"
#include "common/stream.h"
-#include "video_core/command_classes/codecs/vp9_types.h"
-#include "video_core/command_classes/nvdec_common.h"
+#include "video_core/host1x/codecs/vp9_types.h"
+#include "video_core/host1x/nvdec_common.h"
namespace Tegra {
-class GPU;
+
+namespace Host1x {
+class Host1x;
+} // namespace Host1x
+
namespace Decoder {
/// The VpxRangeEncoder, and VpxBitStreamWriter classes are used to compose the
@@ -106,7 +110,7 @@ private:
class VP9 {
public:
- explicit VP9(GPU& gpu_);
+ explicit VP9(Host1x::Host1x& host1x);
~VP9();
VP9(const VP9&) = delete;
@@ -117,7 +121,7 @@ public:
/// Composes the VP9 frame from the GPU state information.
/// Based on the official VP9 spec documentation
- void ComposeFrame(const NvdecCommon::NvdecRegisters& state);
+ void ComposeFrame(const Host1x::NvdecCommon::NvdecRegisters& state);
/// Returns true if the most recent frame was a hidden frame.
[[nodiscard]] bool WasFrameHidden() const {
@@ -162,19 +166,21 @@ private:
void WriteMvProbabilityUpdate(VpxRangeEncoder& writer, u8 new_prob, u8 old_prob);
/// Returns VP9 information from NVDEC provided offset and size
- [[nodiscard]] Vp9PictureInfo GetVp9PictureInfo(const NvdecCommon::NvdecRegisters& state);
+ [[nodiscard]] Vp9PictureInfo GetVp9PictureInfo(
+ const Host1x::NvdecCommon::NvdecRegisters& state);
/// Read and convert NVDEC provided entropy probs to Vp9EntropyProbs struct
void InsertEntropy(u64 offset, Vp9EntropyProbs& dst);
/// Returns frame to be decoded after buffering
- [[nodiscard]] Vp9FrameContainer GetCurrentFrame(const NvdecCommon::NvdecRegisters& state);
+ [[nodiscard]] Vp9FrameContainer GetCurrentFrame(
+ const Host1x::NvdecCommon::NvdecRegisters& state);
/// Use NVDEC providied information to compose the headers for the current frame
[[nodiscard]] std::vector<u8> ComposeCompressedHeader();
[[nodiscard]] VpxBitStreamWriter ComposeUncompressedHeader();
- GPU& gpu;
+ Host1x::Host1x& host1x;
std::vector<u8> frame;
std::array<s8, 4> loop_filter_ref_deltas{};
diff --git a/src/video_core/command_classes/codecs/vp9_types.h b/src/video_core/host1x/codecs/vp9_types.h
index bb3d8df6e..adad8ed7e 100644
--- a/src/video_core/command_classes/codecs/vp9_types.h
+++ b/src/video_core/host1x/codecs/vp9_types.h
@@ -9,7 +9,6 @@
#include "common/common_types.h"
namespace Tegra {
-class GPU;
namespace Decoder {
struct Vp9FrameDimensions {
diff --git a/src/video_core/host1x/control.cpp b/src/video_core/host1x/control.cpp
new file mode 100644
index 000000000..dceefdb7f
--- /dev/null
+++ b/src/video_core/host1x/control.cpp
@@ -0,0 +1,33 @@
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "common/assert.h"
+#include "video_core/host1x/control.h"
+#include "video_core/host1x/host1x.h"
+
+namespace Tegra::Host1x {
+
+Control::Control(Host1x& host1x_) : host1x(host1x_) {}
+
+Control::~Control() = default;
+
+void Control::ProcessMethod(Method method, u32 argument) {
+ switch (method) {
+ case Method::LoadSyncptPayload32:
+ syncpoint_value = argument;
+ break;
+ case Method::WaitSyncpt:
+ case Method::WaitSyncpt32:
+ Execute(argument);
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Control method 0x{:X}", static_cast<u32>(method));
+ break;
+ }
+}
+
+void Control::Execute(u32 data) {
+ host1x.GetSyncpointManager().WaitHost(data, syncpoint_value);
+}
+
+} // namespace Tegra::Host1x
diff --git a/src/video_core/command_classes/host1x.h b/src/video_core/host1x/control.h
index bb48a4381..e117888a3 100644
--- a/src/video_core/command_classes/host1x.h
+++ b/src/video_core/host1x/control.h
@@ -1,15 +1,19 @@
-// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-FileCopyrightText: 2021 Skyline Team and Contributors
+// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "common/common_types.h"
namespace Tegra {
-class GPU;
+
+namespace Host1x {
+
+class Host1x;
class Nvdec;
-class Host1x {
+class Control {
public:
enum class Method : u32 {
WaitSyncpt = 0x8,
@@ -17,8 +21,8 @@ public:
WaitSyncpt32 = 0x50,
};
- explicit Host1x(GPU& gpu);
- ~Host1x();
+ explicit Control(Host1x& host1x);
+ ~Control();
/// Writes the method into the state, Invoke Execute() if encountered
void ProcessMethod(Method method, u32 argument);
@@ -28,7 +32,9 @@ private:
void Execute(u32 data);
u32 syncpoint_value{};
- GPU& gpu;
+ Host1x& host1x;
};
+} // namespace Host1x
+
} // namespace Tegra
diff --git a/src/video_core/host1x/host1x.cpp b/src/video_core/host1x/host1x.cpp
new file mode 100644
index 000000000..7c317a85d
--- /dev/null
+++ b/src/video_core/host1x/host1x.cpp
@@ -0,0 +1,17 @@
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "core/core.h"
+#include "video_core/host1x/host1x.h"
+
+namespace Tegra {
+
+namespace Host1x {
+
+Host1x::Host1x(Core::System& system_)
+ : system{system_}, syncpoint_manager{}, memory_manager{system, 32, 12},
+ allocator{std::make_unique<Common::FlatAllocator<u32, 0, 32>>(1 << 12)} {}
+
+} // namespace Host1x
+
+} // namespace Tegra
diff --git a/src/video_core/host1x/host1x.h b/src/video_core/host1x/host1x.h
new file mode 100644
index 000000000..57082ae54
--- /dev/null
+++ b/src/video_core/host1x/host1x.h
@@ -0,0 +1,57 @@
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include "common/common_types.h"
+
+#include "common/address_space.h"
+#include "video_core/host1x/syncpoint_manager.h"
+#include "video_core/memory_manager.h"
+
+namespace Core {
+class System;
+} // namespace Core
+
+namespace Tegra {
+
+namespace Host1x {
+
+class Host1x {
+public:
+ explicit Host1x(Core::System& system);
+
+ SyncpointManager& GetSyncpointManager() {
+ return syncpoint_manager;
+ }
+
+ const SyncpointManager& GetSyncpointManager() const {
+ return syncpoint_manager;
+ }
+
+ Tegra::MemoryManager& MemoryManager() {
+ return memory_manager;
+ }
+
+ const Tegra::MemoryManager& MemoryManager() const {
+ return memory_manager;
+ }
+
+ Common::FlatAllocator<u32, 0, 32>& Allocator() {
+ return *allocator;
+ }
+
+ const Common::FlatAllocator<u32, 0, 32>& Allocator() const {
+ return *allocator;
+ }
+
+private:
+ Core::System& system;
+ SyncpointManager syncpoint_manager;
+ Tegra::MemoryManager memory_manager;
+ std::unique_ptr<Common::FlatAllocator<u32, 0, 32>> allocator;
+};
+
+} // namespace Host1x
+
+} // namespace Tegra
diff --git a/src/video_core/command_classes/nvdec.cpp b/src/video_core/host1x/nvdec.cpp
index 4fbbe3da6..a4bd5b79f 100644
--- a/src/video_core/command_classes/nvdec.cpp
+++ b/src/video_core/host1x/nvdec.cpp
@@ -2,15 +2,16 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/assert.h"
-#include "video_core/command_classes/nvdec.h"
-#include "video_core/gpu.h"
+#include "video_core/host1x/host1x.h"
+#include "video_core/host1x/nvdec.h"
-namespace Tegra {
+namespace Tegra::Host1x {
#define NVDEC_REG_INDEX(field_name) \
(offsetof(NvdecCommon::NvdecRegisters, field_name) / sizeof(u64))
-Nvdec::Nvdec(GPU& gpu_) : gpu(gpu_), state{}, codec(std::make_unique<Codec>(gpu, state)) {}
+Nvdec::Nvdec(Host1x& host1x_)
+ : host1x(host1x_), state{}, codec(std::make_unique<Codec>(host1x, state)) {}
Nvdec::~Nvdec() = default;
@@ -44,4 +45,4 @@ void Nvdec::Execute() {
}
}
-} // namespace Tegra
+} // namespace Tegra::Host1x
diff --git a/src/video_core/command_classes/nvdec.h b/src/video_core/host1x/nvdec.h
index 488531fc6..3949d5181 100644
--- a/src/video_core/command_classes/nvdec.h
+++ b/src/video_core/host1x/nvdec.h
@@ -6,14 +6,17 @@
#include <memory>
#include <vector>
#include "common/common_types.h"
-#include "video_core/command_classes/codecs/codec.h"
+#include "video_core/host1x/codecs/codec.h"
namespace Tegra {
-class GPU;
+
+namespace Host1x {
+
+class Host1x;
class Nvdec {
public:
- explicit Nvdec(GPU& gpu);
+ explicit Nvdec(Host1x& host1x);
~Nvdec();
/// Writes the method into the state, Invoke Execute() if encountered
@@ -26,8 +29,11 @@ private:
/// Invoke codec to decode a frame
void Execute();
- GPU& gpu;
+ Host1x& host1x;
NvdecCommon::NvdecRegisters state;
std::unique_ptr<Codec> codec;
};
+
+} // namespace Host1x
+
} // namespace Tegra
diff --git a/src/video_core/command_classes/nvdec_common.h b/src/video_core/host1x/nvdec_common.h
index 521e5b52b..49d67ebbe 100644
--- a/src/video_core/command_classes/nvdec_common.h
+++ b/src/video_core/host1x/nvdec_common.h
@@ -7,7 +7,7 @@
#include "common/common_funcs.h"
#include "common/common_types.h"
-namespace Tegra::NvdecCommon {
+namespace Tegra::Host1x::NvdecCommon {
enum class VideoCodec : u64 {
None = 0x0,
@@ -94,4 +94,4 @@ ASSERT_REG_POSITION(vp9_curr_frame_mvs_offset, 0x176);
#undef ASSERT_REG_POSITION
-} // namespace Tegra::NvdecCommon
+} // namespace Tegra::Host1x::NvdecCommon
diff --git a/src/video_core/command_classes/sync_manager.cpp b/src/video_core/host1x/sync_manager.cpp
index 67e58046f..5ef9ea217 100644
--- a/src/video_core/command_classes/sync_manager.cpp
+++ b/src/video_core/host1x/sync_manager.cpp
@@ -3,10 +3,13 @@
#include <algorithm>
#include "sync_manager.h"
-#include "video_core/gpu.h"
+#include "video_core/host1x/host1x.h"
+#include "video_core/host1x/syncpoint_manager.h"
namespace Tegra {
-SyncptIncrManager::SyncptIncrManager(GPU& gpu_) : gpu(gpu_) {}
+namespace Host1x {
+
+SyncptIncrManager::SyncptIncrManager(Host1x& host1x_) : host1x(host1x_) {}
SyncptIncrManager::~SyncptIncrManager() = default;
void SyncptIncrManager::Increment(u32 id) {
@@ -36,8 +39,12 @@ void SyncptIncrManager::IncrementAllDone() {
if (!increments[done_count].complete) {
break;
}
- gpu.IncrementSyncPoint(increments[done_count].syncpt_id);
+ auto& syncpoint_manager = host1x.GetSyncpointManager();
+ syncpoint_manager.IncrementGuest(increments[done_count].syncpt_id);
+ syncpoint_manager.IncrementHost(increments[done_count].syncpt_id);
}
increments.erase(increments.begin(), increments.begin() + done_count);
}
+
+} // namespace Host1x
} // namespace Tegra
diff --git a/src/video_core/command_classes/sync_manager.h b/src/video_core/host1x/sync_manager.h
index 6dfaae080..7bb77fa27 100644
--- a/src/video_core/command_classes/sync_manager.h
+++ b/src/video_core/host1x/sync_manager.h
@@ -8,7 +8,11 @@
#include "common/common_types.h"
namespace Tegra {
-class GPU;
+
+namespace Host1x {
+
+class Host1x;
+
struct SyncptIncr {
u32 id;
u32 class_id;
@@ -21,7 +25,7 @@ struct SyncptIncr {
class SyncptIncrManager {
public:
- explicit SyncptIncrManager(GPU& gpu);
+ explicit SyncptIncrManager(Host1x& host1x);
~SyncptIncrManager();
/// Add syncpoint id and increment all
@@ -41,7 +45,9 @@ private:
std::mutex increment_lock;
u32 current_id{};
- GPU& gpu;
+ Host1x& host1x;
};
+} // namespace Host1x
+
} // namespace Tegra
diff --git a/src/video_core/host1x/syncpoint_manager.cpp b/src/video_core/host1x/syncpoint_manager.cpp
new file mode 100644
index 000000000..a44fc83d3
--- /dev/null
+++ b/src/video_core/host1x/syncpoint_manager.cpp
@@ -0,0 +1,106 @@
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "common/microprofile.h"
+#include "video_core/host1x/syncpoint_manager.h"
+
+namespace Tegra {
+
+namespace Host1x {
+
+MICROPROFILE_DEFINE(GPU_wait, "GPU", "Wait for the GPU", MP_RGB(128, 128, 192));
+
+SyncpointManager::ActionHandle SyncpointManager::RegisterAction(
+ std::atomic<u32>& syncpoint, std::list<RegisteredAction>& action_storage, u32 expected_value,
+ std::function<void()>&& action) {
+ if (syncpoint.load(std::memory_order_acquire) >= expected_value) {
+ action();
+ return {};
+ }
+
+ std::unique_lock lk(guard);
+ if (syncpoint.load(std::memory_order_relaxed) >= expected_value) {
+ action();
+ return {};
+ }
+ auto it = action_storage.begin();
+ while (it != action_storage.end()) {
+ if (it->expected_value >= expected_value) {
+ break;
+ }
+ ++it;
+ }
+ return action_storage.emplace(it, expected_value, std::move(action));
+}
+
+void SyncpointManager::DeregisterAction(std::list<RegisteredAction>& action_storage,
+ ActionHandle& handle) {
+ std::unique_lock lk(guard);
+
+ // We want to ensure the iterator still exists prior to erasing it
+ // Otherwise, if an invalid iterator was passed in then it could lead to UB
+ // It is important to avoid UB in that case since the deregister isn't called from a locked
+ // context
+ for (auto it = action_storage.begin(); it != action_storage.end(); it++) {
+ if (it == handle) {
+ action_storage.erase(it);
+ return;
+ }
+ }
+}
+
+void SyncpointManager::DeregisterGuestAction(u32 syncpoint_id, ActionHandle& handle) {
+ DeregisterAction(guest_action_storage[syncpoint_id], handle);
+}
+
+void SyncpointManager::DeregisterHostAction(u32 syncpoint_id, ActionHandle& handle) {
+ DeregisterAction(host_action_storage[syncpoint_id], handle);
+}
+
+void SyncpointManager::IncrementGuest(u32 syncpoint_id) {
+ Increment(syncpoints_guest[syncpoint_id], wait_guest_cv, guest_action_storage[syncpoint_id]);
+}
+
+void SyncpointManager::IncrementHost(u32 syncpoint_id) {
+ Increment(syncpoints_host[syncpoint_id], wait_host_cv, host_action_storage[syncpoint_id]);
+}
+
+void SyncpointManager::WaitGuest(u32 syncpoint_id, u32 expected_value) {
+ Wait(syncpoints_guest[syncpoint_id], wait_guest_cv, expected_value);
+}
+
+void SyncpointManager::WaitHost(u32 syncpoint_id, u32 expected_value) {
+ MICROPROFILE_SCOPE(GPU_wait);
+ Wait(syncpoints_host[syncpoint_id], wait_host_cv, expected_value);
+}
+
+void SyncpointManager::Increment(std::atomic<u32>& syncpoint, std::condition_variable& wait_cv,
+ std::list<RegisteredAction>& action_storage) {
+ auto new_value{syncpoint.fetch_add(1, std::memory_order_acq_rel) + 1};
+
+ std::unique_lock lk(guard);
+ auto it = action_storage.begin();
+ while (it != action_storage.end()) {
+ if (it->expected_value > new_value) {
+ break;
+ }
+ it->action();
+ it = action_storage.erase(it);
+ }
+ wait_cv.notify_all();
+}
+
+void SyncpointManager::Wait(std::atomic<u32>& syncpoint, std::condition_variable& wait_cv,
+ u32 expected_value) {
+ const auto pred = [&]() { return syncpoint.load(std::memory_order_acquire) >= expected_value; };
+ if (pred()) {
+ return;
+ }
+
+ std::unique_lock lk(guard);
+ wait_cv.wait(lk, pred);
+}
+
+} // namespace Host1x
+
+} // namespace Tegra
diff --git a/src/video_core/host1x/syncpoint_manager.h b/src/video_core/host1x/syncpoint_manager.h
new file mode 100644
index 000000000..50a264e23
--- /dev/null
+++ b/src/video_core/host1x/syncpoint_manager.h
@@ -0,0 +1,98 @@
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#include <array>
+#include <atomic>
+#include <condition_variable>
+#include <functional>
+#include <list>
+#include <mutex>
+
+#include "common/common_types.h"
+
+namespace Tegra {
+
+namespace Host1x {
+
+class SyncpointManager {
+public:
+ u32 GetGuestSyncpointValue(u32 id) const {
+ return syncpoints_guest[id].load(std::memory_order_acquire);
+ }
+
+ u32 GetHostSyncpointValue(u32 id) const {
+ return syncpoints_host[id].load(std::memory_order_acquire);
+ }
+
+ struct RegisteredAction {
+ explicit RegisteredAction(u32 expected_value_, std::function<void()>&& action_)
+ : expected_value{expected_value_}, action{std::move(action_)} {}
+ u32 expected_value;
+ std::function<void()> action;
+ };
+ using ActionHandle = std::list<RegisteredAction>::iterator;
+
+ template <typename Func>
+ ActionHandle RegisterGuestAction(u32 syncpoint_id, u32 expected_value, Func&& action) {
+ std::function<void()> func(action);
+ return RegisterAction(syncpoints_guest[syncpoint_id], guest_action_storage[syncpoint_id],
+ expected_value, std::move(func));
+ }
+
+ template <typename Func>
+ ActionHandle RegisterHostAction(u32 syncpoint_id, u32 expected_value, Func&& action) {
+ std::function<void()> func(action);
+ return RegisterAction(syncpoints_host[syncpoint_id], host_action_storage[syncpoint_id],
+ expected_value, std::move(func));
+ }
+
+ void DeregisterGuestAction(u32 syncpoint_id, ActionHandle& handle);
+
+ void DeregisterHostAction(u32 syncpoint_id, ActionHandle& handle);
+
+ void IncrementGuest(u32 syncpoint_id);
+
+ void IncrementHost(u32 syncpoint_id);
+
+ void WaitGuest(u32 syncpoint_id, u32 expected_value);
+
+ void WaitHost(u32 syncpoint_id, u32 expected_value);
+
+ bool IsReadyGuest(u32 syncpoint_id, u32 expected_value) const {
+ return syncpoints_guest[syncpoint_id].load(std::memory_order_acquire) >= expected_value;
+ }
+
+ bool IsReadyHost(u32 syncpoint_id, u32 expected_value) const {
+ return syncpoints_host[syncpoint_id].load(std::memory_order_acquire) >= expected_value;
+ }
+
+private:
+ void Increment(std::atomic<u32>& syncpoint, std::condition_variable& wait_cv,
+ std::list<RegisteredAction>& action_storage);
+
+ ActionHandle RegisterAction(std::atomic<u32>& syncpoint,
+ std::list<RegisteredAction>& action_storage, u32 expected_value,
+ std::function<void()>&& action);
+
+ void DeregisterAction(std::list<RegisteredAction>& action_storage, ActionHandle& handle);
+
+ void Wait(std::atomic<u32>& syncpoint, std::condition_variable& wait_cv, u32 expected_value);
+
+ static constexpr size_t NUM_MAX_SYNCPOINTS = 192;
+
+ std::array<std::atomic<u32>, NUM_MAX_SYNCPOINTS> syncpoints_guest{};
+ std::array<std::atomic<u32>, NUM_MAX_SYNCPOINTS> syncpoints_host{};
+
+ std::array<std::list<RegisteredAction>, NUM_MAX_SYNCPOINTS> guest_action_storage;
+ std::array<std::list<RegisteredAction>, NUM_MAX_SYNCPOINTS> host_action_storage;
+
+ std::mutex guard;
+ std::condition_variable wait_guest_cv;
+ std::condition_variable wait_host_cv;
+};
+
+} // namespace Host1x
+
+} // namespace Tegra
diff --git a/src/video_core/command_classes/vic.cpp b/src/video_core/host1x/vic.cpp
index 7c17df353..ac0b7d20e 100644
--- a/src/video_core/command_classes/vic.cpp
+++ b/src/video_core/host1x/vic.cpp
@@ -18,14 +18,17 @@ extern "C" {
#include "common/bit_field.h"
#include "common/logging/log.h"
-#include "video_core/command_classes/nvdec.h"
-#include "video_core/command_classes/vic.h"
#include "video_core/engines/maxwell_3d.h"
-#include "video_core/gpu.h"
+#include "video_core/host1x/host1x.h"
+#include "video_core/host1x/nvdec.h"
+#include "video_core/host1x/vic.h"
#include "video_core/memory_manager.h"
#include "video_core/textures/decoders.h"
namespace Tegra {
+
+namespace Host1x {
+
namespace {
enum class VideoPixelFormat : u64_le {
RGBA8 = 0x1f,
@@ -46,8 +49,8 @@ union VicConfig {
BitField<46, 14, u64_le> surface_height_minus1;
};
-Vic::Vic(GPU& gpu_, std::shared_ptr<Nvdec> nvdec_processor_)
- : gpu(gpu_),
+Vic::Vic(Host1x& host1x_, std::shared_ptr<Nvdec> nvdec_processor_)
+ : host1x(host1x_),
nvdec_processor(std::move(nvdec_processor_)), converted_frame_buffer{nullptr, av_free} {}
Vic::~Vic() = default;
@@ -78,7 +81,7 @@ void Vic::Execute() {
LOG_ERROR(Service_NVDRV, "VIC Luma address not set.");
return;
}
- const VicConfig config{gpu.MemoryManager().Read<u64>(config_struct_address + 0x20)};
+ const VicConfig config{host1x.MemoryManager().Read<u64>(config_struct_address + 0x20)};
const AVFramePtr frame_ptr = nvdec_processor->GetFrame();
const auto* frame = frame_ptr.get();
if (!frame) {
@@ -153,15 +156,16 @@ void Vic::WriteRGBFrame(const AVFrame* frame, const VicConfig& config) {
const u32 block_height = static_cast<u32>(config.block_linear_height_log2);
const auto size = Texture::CalculateSize(true, 4, width, height, 1, block_height, 0);
luma_buffer.resize(size);
- Texture::SwizzleSubrect(width, height, width * 4, width, 4, luma_buffer.data(),
- converted_frame_buf_addr, block_height, 0, 0);
+ std::span<const u8> frame_buff(converted_frame_buf_addr, 4 * width * height);
+ Texture::SwizzleSubrect(luma_buffer, frame_buff, 4, width, height, 1, 0, 0, width, height,
+ block_height, 0, width * 4);
- gpu.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(), size);
+ host1x.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(), size);
} else {
// send pitch linear frame
const size_t linear_size = width * height * 4;
- gpu.MemoryManager().WriteBlock(output_surface_luma_address, converted_frame_buf_addr,
- linear_size);
+ host1x.MemoryManager().WriteBlock(output_surface_luma_address, converted_frame_buf_addr,
+ linear_size);
}
}
@@ -189,8 +193,8 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
luma_buffer[dst + x] = luma_src[src + x];
}
}
- gpu.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(),
- luma_buffer.size());
+ host1x.MemoryManager().WriteBlock(output_surface_luma_address, luma_buffer.data(),
+ luma_buffer.size());
// Chroma
const std::size_t half_height = frame_height / 2;
@@ -231,8 +235,10 @@ void Vic::WriteYUVFrame(const AVFrame* frame, const VicConfig& config) {
ASSERT(false);
break;
}
- gpu.MemoryManager().WriteBlock(output_surface_chroma_address, chroma_buffer.data(),
- chroma_buffer.size());
+ host1x.MemoryManager().WriteBlock(output_surface_chroma_address, chroma_buffer.data(),
+ chroma_buffer.size());
}
+} // namespace Host1x
+
} // namespace Tegra
diff --git a/src/video_core/command_classes/vic.h b/src/video_core/host1x/vic.h
index 010daa6b6..2b78786e8 100644
--- a/src/video_core/command_classes/vic.h
+++ b/src/video_core/host1x/vic.h
@@ -10,7 +10,10 @@
struct SwsContext;
namespace Tegra {
-class GPU;
+
+namespace Host1x {
+
+class Host1x;
class Nvdec;
union VicConfig;
@@ -25,7 +28,7 @@ public:
SetOutputSurfaceChromaUnusedOffset = 0x1ca
};
- explicit Vic(GPU& gpu, std::shared_ptr<Nvdec> nvdec_processor);
+ explicit Vic(Host1x& host1x, std::shared_ptr<Nvdec> nvdec_processor);
~Vic();
@@ -39,8 +42,8 @@ private:
void WriteYUVFrame(const AVFrame* frame, const VicConfig& config);
- GPU& gpu;
- std::shared_ptr<Tegra::Nvdec> nvdec_processor;
+ Host1x& host1x;
+ std::shared_ptr<Tegra::Host1x::Nvdec> nvdec_processor;
/// Avoid reallocation of the following buffers every frame, as their
/// size does not change during a stream
@@ -58,4 +61,6 @@ private:
s32 scaler_height{};
};
+} // namespace Host1x
+
} // namespace Tegra
diff --git a/src/video_core/host_shaders/astc_decoder.comp b/src/video_core/host_shaders/astc_decoder.comp
index 3441a5fe5..d608678a3 100644
--- a/src/video_core/host_shaders/astc_decoder.comp
+++ b/src/video_core/host_shaders/astc_decoder.comp
@@ -1065,7 +1065,7 @@ TexelWeightParams DecodeBlockInfo() {
void FillError(ivec3 coord) {
for (uint j = 0; j < block_dims.y; j++) {
for (uint i = 0; i < block_dims.x; i++) {
- imageStore(dest_image, coord + ivec3(i, j, 0), vec4(1.0, 1.0, 0.0, 1.0));
+ imageStore(dest_image, coord + ivec3(i, j, 0), vec4(0.0, 0.0, 0.0, 0.0));
}
}
}
diff --git a/src/video_core/macro/macro.cpp b/src/video_core/macro/macro.cpp
index 43f8b5904..f61d5998e 100644
--- a/src/video_core/macro/macro.cpp
+++ b/src/video_core/macro/macro.cpp
@@ -8,6 +8,7 @@
#include <boost/container_hash/hash.hpp>
+#include <fstream>
#include "common/assert.h"
#include "common/fs/fs.h"
#include "common/fs/path_util.h"
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp
index 58382755b..f896591bf 100644
--- a/src/video_core/macro/macro_hle.cpp
+++ b/src/video_core/macro/macro_hle.cpp
@@ -3,6 +3,8 @@
#include <array>
#include <vector>
+#include "common/scope_exit.h"
+#include "video_core/dirty_flags.h"
#include "video_core/engines/maxwell_3d.h"
#include "video_core/macro/macro.h"
#include "video_core/macro/macro_hle.h"
@@ -19,71 +21,116 @@ void HLE_771BB18C62444DA0(Engines::Maxwell3D& maxwell3d, const std::vector<u32>&
maxwell3d.regs.draw.topology.Assign(
static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0] & 0x3ffffff));
- maxwell3d.regs.vb_base_instance = parameters[5];
- maxwell3d.mme_draw.instance_count = instance_count;
- maxwell3d.regs.vb_element_base = parameters[3];
- maxwell3d.regs.index_array.count = parameters[1];
- maxwell3d.regs.index_array.first = parameters[4];
+ maxwell3d.regs.global_base_instance_index = parameters[5];
+ maxwell3d.regs.global_base_vertex_index = parameters[3];
+ maxwell3d.regs.index_buffer.count = parameters[1];
+ maxwell3d.regs.index_buffer.first = parameters[4];
if (maxwell3d.ShouldExecute()) {
- maxwell3d.Rasterizer().Draw(true, true);
+ maxwell3d.Rasterizer().Draw(true, instance_count);
}
- maxwell3d.regs.index_array.count = 0;
- maxwell3d.mme_draw.instance_count = 0;
- maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
+ maxwell3d.regs.index_buffer.count = 0;
}
void HLE_0D61FC9FAAC9FCAD(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) {
- const u32 count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]);
+ const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]);
maxwell3d.regs.vertex_buffer.first = parameters[3];
maxwell3d.regs.vertex_buffer.count = parameters[1];
- maxwell3d.regs.vb_base_instance = parameters[4];
+ maxwell3d.regs.global_base_instance_index = parameters[4];
maxwell3d.regs.draw.topology.Assign(
static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]));
- maxwell3d.mme_draw.instance_count = count;
if (maxwell3d.ShouldExecute()) {
- maxwell3d.Rasterizer().Draw(false, true);
+ maxwell3d.Rasterizer().Draw(false, instance_count);
}
maxwell3d.regs.vertex_buffer.count = 0;
- maxwell3d.mme_draw.instance_count = 0;
- maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
}
void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) {
const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]);
const u32 element_base = parameters[4];
const u32 base_instance = parameters[5];
- maxwell3d.regs.index_array.first = parameters[3];
- maxwell3d.regs.reg_array[0x446] = element_base; // vertex id base?
- maxwell3d.regs.index_array.count = parameters[1];
- maxwell3d.regs.vb_element_base = element_base;
- maxwell3d.regs.vb_base_instance = base_instance;
- maxwell3d.mme_draw.instance_count = instance_count;
- maxwell3d.CallMethodFromMME(0x8e3, 0x640);
- maxwell3d.CallMethodFromMME(0x8e4, element_base);
- maxwell3d.CallMethodFromMME(0x8e5, base_instance);
+ maxwell3d.regs.index_buffer.first = parameters[3];
+ maxwell3d.regs.vertex_id_base = element_base;
+ maxwell3d.regs.index_buffer.count = parameters[1];
+ maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
+ maxwell3d.regs.global_base_vertex_index = element_base;
+ maxwell3d.regs.global_base_instance_index = base_instance;
+ maxwell3d.CallMethod(0x8e3, 0x640, true);
+ maxwell3d.CallMethod(0x8e4, element_base, true);
+ maxwell3d.CallMethod(0x8e5, base_instance, true);
maxwell3d.regs.draw.topology.Assign(
static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]));
if (maxwell3d.ShouldExecute()) {
- maxwell3d.Rasterizer().Draw(true, true);
+ maxwell3d.Rasterizer().Draw(true, instance_count);
+ }
+ maxwell3d.regs.vertex_id_base = 0x0;
+ maxwell3d.regs.index_buffer.count = 0;
+ maxwell3d.regs.global_base_vertex_index = 0x0;
+ maxwell3d.regs.global_base_instance_index = 0x0;
+ maxwell3d.CallMethod(0x8e3, 0x640, true);
+ maxwell3d.CallMethod(0x8e4, 0x0, true);
+ maxwell3d.CallMethod(0x8e5, 0x0, true);
+}
+
+// Multidraw Indirect
+void HLE_3F5E74B9C9A50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) {
+ SCOPE_EXIT({
+ // Clean everything.
+ maxwell3d.regs.vertex_id_base = 0x0;
+ maxwell3d.regs.index_buffer.count = 0;
+ maxwell3d.regs.global_base_vertex_index = 0x0;
+ maxwell3d.regs.global_base_instance_index = 0x0;
+ maxwell3d.CallMethod(0x8e3, 0x640, true);
+ maxwell3d.CallMethod(0x8e4, 0x0, true);
+ maxwell3d.CallMethod(0x8e5, 0x0, true);
+ maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
+ });
+ const u32 start_indirect = parameters[0];
+ const u32 end_indirect = parameters[1];
+ if (start_indirect >= end_indirect) {
+ // Nothing to do.
+ return;
+ }
+ const auto topology =
+ static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[2]);
+ maxwell3d.regs.draw.topology.Assign(topology);
+ const u32 padding = parameters[3];
+ const std::size_t max_draws = parameters[4];
+
+ const u32 indirect_words = 5 + padding;
+ const std::size_t first_draw = start_indirect;
+ const std::size_t effective_draws = end_indirect - start_indirect;
+ const std::size_t last_draw = start_indirect + std::min(effective_draws, max_draws);
+
+ for (std::size_t index = first_draw; index < last_draw; index++) {
+ const std::size_t base = index * indirect_words + 5;
+ const u32 num_vertices = parameters[base];
+ const u32 instance_count = parameters[base + 1];
+ const u32 first_index = parameters[base + 2];
+ const u32 base_vertex = parameters[base + 3];
+ const u32 base_instance = parameters[base + 4];
+ maxwell3d.regs.index_buffer.first = first_index;
+ maxwell3d.regs.vertex_id_base = base_vertex;
+ maxwell3d.regs.index_buffer.count = num_vertices;
+ maxwell3d.regs.global_base_vertex_index = base_vertex;
+ maxwell3d.regs.global_base_instance_index = base_instance;
+ maxwell3d.CallMethod(0x8e3, 0x640, true);
+ maxwell3d.CallMethod(0x8e4, base_vertex, true);
+ maxwell3d.CallMethod(0x8e5, base_instance, true);
+ maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
+ if (maxwell3d.ShouldExecute()) {
+ maxwell3d.Rasterizer().Draw(true, instance_count);
+ }
}
- maxwell3d.regs.reg_array[0x446] = 0x0; // vertex id base?
- maxwell3d.regs.index_array.count = 0;
- maxwell3d.regs.vb_element_base = 0x0;
- maxwell3d.regs.vb_base_instance = 0x0;
- maxwell3d.mme_draw.instance_count = 0;
- maxwell3d.CallMethodFromMME(0x8e3, 0x640);
- maxwell3d.CallMethodFromMME(0x8e4, 0x0);
- maxwell3d.CallMethodFromMME(0x8e5, 0x0);
- maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
}
-constexpr std::array<std::pair<u64, HLEFunction>, 3> hle_funcs{{
+constexpr std::array<std::pair<u64, HLEFunction>, 4> hle_funcs{{
{0x771BB18C62444DA0, &HLE_771BB18C62444DA0},
{0x0D61FC9FAAC9FCAD, &HLE_0D61FC9FAAC9FCAD},
{0x0217920100488FF7, &HLE_0217920100488FF7},
+ {0x3F5E74B9C9A50164, &HLE_3F5E74B9C9A50164},
}};
class HLEMacroImpl final : public CachedMacro {
@@ -99,6 +146,7 @@ private:
Engines::Maxwell3D& maxwell3d;
HLEFunction func;
};
+
} // Anonymous namespace
HLEMacro::HLEMacro(Engines::Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {}
diff --git a/src/video_core/macro/macro_interpreter.cpp b/src/video_core/macro/macro_interpreter.cpp
index f670b1bca..c0d32c112 100644
--- a/src/video_core/macro/macro_interpreter.cpp
+++ b/src/video_core/macro/macro_interpreter.cpp
@@ -335,7 +335,7 @@ void MacroInterpreterImpl::SetMethodAddress(u32 address) {
}
void MacroInterpreterImpl::Send(u32 value) {
- maxwell3d.CallMethodFromMME(method_address.address, value);
+ maxwell3d.CallMethod(method_address.address, value, true);
// Increment the method address by the method increment.
method_address.address.Assign(method_address.address.Value() +
method_address.increment.Value());
diff --git a/src/video_core/macro/macro_jit_x64.cpp b/src/video_core/macro/macro_jit_x64.cpp
index aca25d902..25c1ce798 100644
--- a/src/video_core/macro/macro_jit_x64.cpp
+++ b/src/video_core/macro/macro_jit_x64.cpp
@@ -279,28 +279,13 @@ void MacroJITx64Impl::Compile_ExtractInsert(Macro::Opcode opcode) {
auto dst = Compile_GetRegister(opcode.src_a, RESULT);
auto src = Compile_GetRegister(opcode.src_b, eax);
- if (opcode.bf_src_bit != 0 && opcode.bf_src_bit != 31) {
- shr(src, opcode.bf_src_bit);
- } else if (opcode.bf_src_bit == 31) {
- xor_(src, src);
- }
- // Don't bother masking the whole register since we're using a 32 bit register
- if (opcode.bf_size != 31 && opcode.bf_size != 0) {
- and_(src, opcode.GetBitfieldMask());
- } else if (opcode.bf_size == 0) {
- xor_(src, src);
- }
- if (opcode.bf_dst_bit != 31 && opcode.bf_dst_bit != 0) {
- shl(src, opcode.bf_dst_bit);
- } else if (opcode.bf_dst_bit == 31) {
- xor_(src, src);
- }
-
const u32 mask = ~(opcode.GetBitfieldMask() << opcode.bf_dst_bit);
- if (mask != 0xffffffff) {
- and_(dst, mask);
- }
+ and_(dst, mask);
+ shr(src, opcode.bf_src_bit);
+ and_(src, opcode.GetBitfieldMask());
+ shl(src, opcode.bf_dst_bit);
or_(dst, src);
+
Compile_ProcessResult(opcode.result_operation, opcode.dst);
}
@@ -309,17 +294,9 @@ void MacroJITx64Impl::Compile_ExtractShiftLeftImmediate(Macro::Opcode opcode) {
const auto src = Compile_GetRegister(opcode.src_b, RESULT);
shr(src, dst.cvt8());
- if (opcode.bf_size != 0 && opcode.bf_size != 31) {
- and_(src, opcode.GetBitfieldMask());
- } else if (opcode.bf_size == 0) {
- xor_(src, src);
- }
+ and_(src, opcode.GetBitfieldMask());
+ shl(src, opcode.bf_dst_bit);
- if (opcode.bf_dst_bit != 0 && opcode.bf_dst_bit != 31) {
- shl(src, opcode.bf_dst_bit);
- } else if (opcode.bf_dst_bit == 31) {
- xor_(src, src);
- }
Compile_ProcessResult(opcode.result_operation, opcode.dst);
}
@@ -327,13 +304,8 @@ void MacroJITx64Impl::Compile_ExtractShiftLeftRegister(Macro::Opcode opcode) {
const auto dst = Compile_GetRegister(opcode.src_a, ecx);
const auto src = Compile_GetRegister(opcode.src_b, RESULT);
- if (opcode.bf_src_bit != 0) {
- shr(src, opcode.bf_src_bit);
- }
-
- if (opcode.bf_size != 31) {
- and_(src, opcode.GetBitfieldMask());
- }
+ shr(src, opcode.bf_src_bit);
+ and_(src, opcode.GetBitfieldMask());
shl(src, dst.cvt8());
Compile_ProcessResult(opcode.result_operation, opcode.dst);
@@ -374,7 +346,7 @@ void MacroJITx64Impl::Compile_Read(Macro::Opcode opcode) {
}
void Send(Engines::Maxwell3D* maxwell3d, Macro::MethodAddress method_address, u32 value) {
- maxwell3d->CallMethodFromMME(method_address.address, value);
+ maxwell3d->CallMethod(method_address.address, value, true);
}
void MacroJITx64Impl::Compile_Send(Xbyak::Reg32 value) {
@@ -429,17 +401,11 @@ void MacroJITx64Impl::Compile_Branch(Macro::Opcode opcode) {
Xbyak::Label handle_post_exit{};
Xbyak::Label skip{};
jmp(skip, T_NEAR);
- if (opcode.is_exit) {
- L(handle_post_exit);
- // Execute 1 instruction
- mov(BRANCH_HOLDER, end_of_code);
- // Jump to next instruction to skip delay slot check
- jmp(labels[jump_address], T_NEAR);
- } else {
- L(handle_post_exit);
- xor_(BRANCH_HOLDER, BRANCH_HOLDER);
- jmp(labels[jump_address], T_NEAR);
- }
+
+ L(handle_post_exit);
+ xor_(BRANCH_HOLDER, BRANCH_HOLDER);
+ jmp(labels[jump_address], T_NEAR);
+
L(skip);
mov(BRANCH_HOLDER, handle_post_exit);
jmp(delay_skip[pc], T_NEAR);
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index bf9eb735d..384350dbd 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -7,6 +7,7 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
+#include "core/device_memory.h"
#include "core/hle/kernel/k_page_table.h"
#include "core/hle/kernel/k_process.h"
#include "core/memory.h"
@@ -16,172 +17,239 @@
namespace Tegra {
-MemoryManager::MemoryManager(Core::System& system_)
- : system{system_}, page_table(page_table_size) {}
+std::atomic<size_t> MemoryManager::unique_identifier_generator{};
+
+MemoryManager::MemoryManager(Core::System& system_, u64 address_space_bits_, u64 big_page_bits_,
+ u64 page_bits_)
+ : system{system_}, memory{system.Memory()}, device_memory{system.DeviceMemory()},
+ address_space_bits{address_space_bits_}, page_bits{page_bits_}, big_page_bits{big_page_bits_},
+ entries{}, big_entries{}, page_table{address_space_bits, address_space_bits + page_bits - 38,
+ page_bits != big_page_bits ? page_bits : 0},
+ unique_identifier{unique_identifier_generator.fetch_add(1, std::memory_order_acq_rel)} {
+ address_space_size = 1ULL << address_space_bits;
+ page_size = 1ULL << page_bits;
+ page_mask = page_size - 1ULL;
+ big_page_size = 1ULL << big_page_bits;
+ big_page_mask = big_page_size - 1ULL;
+ const u64 page_table_bits = address_space_bits - page_bits;
+ const u64 big_page_table_bits = address_space_bits - big_page_bits;
+ const u64 page_table_size = 1ULL << page_table_bits;
+ const u64 big_page_table_size = 1ULL << big_page_table_bits;
+ page_table_mask = page_table_size - 1;
+ big_page_table_mask = big_page_table_size - 1;
+
+ big_entries.resize(big_page_table_size / 32, 0);
+ big_page_table_cpu.resize(big_page_table_size);
+ big_page_continous.resize(big_page_table_size / continous_bits, 0);
+ std::array<PTEKind, 32> kind_valus;
+ kind_valus.fill(PTEKind::INVALID);
+ big_kinds.resize(big_page_table_size / 32, kind_valus);
+ entries.resize(page_table_size / 32, 0);
+ kinds.resize(big_page_table_size / 32, kind_valus);
+}
MemoryManager::~MemoryManager() = default;
-void MemoryManager::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) {
- rasterizer = rasterizer_;
-}
-
-GPUVAddr MemoryManager::UpdateRange(GPUVAddr gpu_addr, PageEntry page_entry, std::size_t size) {
- u64 remaining_size{size};
- for (u64 offset{}; offset < size; offset += page_size) {
- if (remaining_size < page_size) {
- SetPageEntry(gpu_addr + offset, page_entry + offset, remaining_size);
- } else {
- SetPageEntry(gpu_addr + offset, page_entry + offset);
- }
- remaining_size -= page_size;
+template <bool is_big_page>
+MemoryManager::EntryType MemoryManager::GetEntry(size_t position) const {
+ if constexpr (is_big_page) {
+ position = position >> big_page_bits;
+ const u64 entry_mask = big_entries[position / 32];
+ const size_t sub_index = position % 32;
+ return static_cast<EntryType>((entry_mask >> (2 * sub_index)) & 0x03ULL);
+ } else {
+ position = position >> page_bits;
+ const u64 entry_mask = entries[position / 32];
+ const size_t sub_index = position % 32;
+ return static_cast<EntryType>((entry_mask >> (2 * sub_index)) & 0x03ULL);
}
- return gpu_addr;
}
-GPUVAddr MemoryManager::Map(VAddr cpu_addr, GPUVAddr gpu_addr, std::size_t size) {
- const auto it = std::ranges::lower_bound(map_ranges, gpu_addr, {}, &MapRange::first);
- if (it != map_ranges.end() && it->first == gpu_addr) {
- it->second = size;
+template <bool is_big_page>
+void MemoryManager::SetEntry(size_t position, MemoryManager::EntryType entry) {
+ if constexpr (is_big_page) {
+ position = position >> big_page_bits;
+ const u64 entry_mask = big_entries[position / 32];
+ const size_t sub_index = position % 32;
+ big_entries[position / 32] =
+ (~(3ULL << sub_index * 2) & entry_mask) | (static_cast<u64>(entry) << sub_index * 2);
} else {
- map_ranges.insert(it, MapRange{gpu_addr, size});
+ position = position >> page_bits;
+ const u64 entry_mask = entries[position / 32];
+ const size_t sub_index = position % 32;
+ entries[position / 32] =
+ (~(3ULL << sub_index * 2) & entry_mask) | (static_cast<u64>(entry) << sub_index * 2);
}
- return UpdateRange(gpu_addr, cpu_addr, size);
}
-GPUVAddr MemoryManager::MapAllocate(VAddr cpu_addr, std::size_t size, std::size_t align) {
- return Map(cpu_addr, *FindFreeRange(size, align), size);
+PTEKind MemoryManager::GetPageKind(GPUVAddr gpu_addr) const {
+ auto entry = GetEntry<true>(gpu_addr);
+ if (entry == EntryType::Mapped || entry == EntryType::Reserved) [[likely]] {
+ return GetKind<true>(gpu_addr);
+ } else {
+ return GetKind<false>(gpu_addr);
+ }
}
-GPUVAddr MemoryManager::MapAllocate32(VAddr cpu_addr, std::size_t size) {
- const std::optional<GPUVAddr> gpu_addr = FindFreeRange(size, 1, true);
- ASSERT(gpu_addr);
- return Map(cpu_addr, *gpu_addr, size);
+template <bool is_big_page>
+PTEKind MemoryManager::GetKind(size_t position) const {
+ if constexpr (is_big_page) {
+ position = position >> big_page_bits;
+ const size_t sub_index = position % 32;
+ return big_kinds[position / 32][sub_index];
+ } else {
+ position = position >> page_bits;
+ const size_t sub_index = position % 32;
+ return kinds[position / 32][sub_index];
+ }
}
-void MemoryManager::Unmap(GPUVAddr gpu_addr, std::size_t size) {
- if (size == 0) {
- return;
- }
- const auto it = std::ranges::lower_bound(map_ranges, gpu_addr, {}, &MapRange::first);
- if (it != map_ranges.end()) {
- ASSERT(it->first == gpu_addr);
- map_ranges.erase(it);
+template <bool is_big_page>
+void MemoryManager::SetKind(size_t position, PTEKind kind) {
+ if constexpr (is_big_page) {
+ position = position >> big_page_bits;
+ const size_t sub_index = position % 32;
+ big_kinds[position / 32][sub_index] = kind;
} else {
- ASSERT_MSG(false, "Unmapping non-existent GPU address=0x{:x}", gpu_addr);
+ position = position >> page_bits;
+ const size_t sub_index = position % 32;
+ kinds[position / 32][sub_index] = kind;
}
- const auto submapped_ranges = GetSubmappedRange(gpu_addr, size);
-
- for (const auto& [map_addr, map_size] : submapped_ranges) {
- // Flush and invalidate through the GPU interface, to be asynchronous if possible.
- const std::optional<VAddr> cpu_addr = GpuToCpuAddress(map_addr);
- ASSERT(cpu_addr);
+}
- rasterizer->UnmapMemory(*cpu_addr, map_size);
- }
+inline bool MemoryManager::IsBigPageContinous(size_t big_page_index) const {
+ const u64 entry_mask = big_page_continous[big_page_index / continous_bits];
+ const size_t sub_index = big_page_index % continous_bits;
+ return ((entry_mask >> sub_index) & 0x1ULL) != 0;
+}
- UpdateRange(gpu_addr, PageEntry::State::Unmapped, size);
+inline void MemoryManager::SetBigPageContinous(size_t big_page_index, bool value) {
+ const u64 continous_mask = big_page_continous[big_page_index / continous_bits];
+ const size_t sub_index = big_page_index % continous_bits;
+ big_page_continous[big_page_index / continous_bits] =
+ (~(1ULL << sub_index) & continous_mask) | (value ? 1ULL << sub_index : 0);
}
-std::optional<GPUVAddr> MemoryManager::AllocateFixed(GPUVAddr gpu_addr, std::size_t size) {
+template <MemoryManager::EntryType entry_type>
+GPUVAddr MemoryManager::PageTableOp(GPUVAddr gpu_addr, [[maybe_unused]] VAddr cpu_addr, size_t size,
+ PTEKind kind) {
+ [[maybe_unused]] u64 remaining_size{size};
+ if constexpr (entry_type == EntryType::Mapped) {
+ page_table.ReserveRange(gpu_addr, size);
+ }
for (u64 offset{}; offset < size; offset += page_size) {
- if (!GetPageEntry(gpu_addr + offset).IsUnmapped()) {
- return std::nullopt;
+ const GPUVAddr current_gpu_addr = gpu_addr + offset;
+ [[maybe_unused]] const auto current_entry_type = GetEntry<false>(current_gpu_addr);
+ SetEntry<false>(current_gpu_addr, entry_type);
+ SetKind<false>(current_gpu_addr, kind);
+ if (current_entry_type != entry_type) {
+ rasterizer->ModifyGPUMemory(unique_identifier, gpu_addr, page_size);
+ }
+ if constexpr (entry_type == EntryType::Mapped) {
+ const VAddr current_cpu_addr = cpu_addr + offset;
+ const auto index = PageEntryIndex<false>(current_gpu_addr);
+ const u32 sub_value = static_cast<u32>(current_cpu_addr >> cpu_page_bits);
+ page_table[index] = sub_value;
}
+ remaining_size -= page_size;
}
-
- return UpdateRange(gpu_addr, PageEntry::State::Allocated, size);
-}
-
-GPUVAddr MemoryManager::Allocate(std::size_t size, std::size_t align) {
- return *AllocateFixed(*FindFreeRange(size, align), size);
+ return gpu_addr;
}
-void MemoryManager::TryLockPage(PageEntry page_entry, std::size_t size) {
- if (!page_entry.IsValid()) {
- return;
+template <MemoryManager::EntryType entry_type>
+GPUVAddr MemoryManager::BigPageTableOp(GPUVAddr gpu_addr, [[maybe_unused]] VAddr cpu_addr,
+ size_t size, PTEKind kind) {
+ [[maybe_unused]] u64 remaining_size{size};
+ for (u64 offset{}; offset < size; offset += big_page_size) {
+ const GPUVAddr current_gpu_addr = gpu_addr + offset;
+ [[maybe_unused]] const auto current_entry_type = GetEntry<true>(current_gpu_addr);
+ SetEntry<true>(current_gpu_addr, entry_type);
+ SetKind<true>(current_gpu_addr, kind);
+ if (current_entry_type != entry_type) {
+ rasterizer->ModifyGPUMemory(unique_identifier, gpu_addr, big_page_size);
+ }
+ if constexpr (entry_type == EntryType::Mapped) {
+ const VAddr current_cpu_addr = cpu_addr + offset;
+ const auto index = PageEntryIndex<true>(current_gpu_addr);
+ const u32 sub_value = static_cast<u32>(current_cpu_addr >> cpu_page_bits);
+ big_page_table_cpu[index] = sub_value;
+ const bool is_continous = ([&] {
+ uintptr_t base_ptr{
+ reinterpret_cast<uintptr_t>(memory.GetPointerSilent(current_cpu_addr))};
+ if (base_ptr == 0) {
+ return false;
+ }
+ for (VAddr start_cpu = current_cpu_addr + page_size;
+ start_cpu < current_cpu_addr + big_page_size; start_cpu += page_size) {
+ base_ptr += page_size;
+ auto next_ptr = reinterpret_cast<uintptr_t>(memory.GetPointerSilent(start_cpu));
+ if (next_ptr == 0 || base_ptr != next_ptr) {
+ return false;
+ }
+ }
+ return true;
+ })();
+ SetBigPageContinous(index, is_continous);
+ }
+ remaining_size -= big_page_size;
}
-
- ASSERT(system.CurrentProcess()
- ->PageTable()
- .LockForDeviceAddressSpace(page_entry.ToAddress(), size)
- .IsSuccess());
+ return gpu_addr;
}
-void MemoryManager::TryUnlockPage(PageEntry page_entry, std::size_t size) {
- if (!page_entry.IsValid()) {
- return;
- }
-
- ASSERT(system.CurrentProcess()
- ->PageTable()
- .UnlockForDeviceAddressSpace(page_entry.ToAddress(), size)
- .IsSuccess());
+void MemoryManager::BindRasterizer(VideoCore::RasterizerInterface* rasterizer_) {
+ rasterizer = rasterizer_;
}
-PageEntry MemoryManager::GetPageEntry(GPUVAddr gpu_addr) const {
- return page_table[PageEntryIndex(gpu_addr)];
+GPUVAddr MemoryManager::Map(GPUVAddr gpu_addr, VAddr cpu_addr, std::size_t size, PTEKind kind,
+ bool is_big_pages) {
+ if (is_big_pages) [[likely]] {
+ return BigPageTableOp<EntryType::Mapped>(gpu_addr, cpu_addr, size, kind);
+ }
+ return PageTableOp<EntryType::Mapped>(gpu_addr, cpu_addr, size, kind);
}
-void MemoryManager::SetPageEntry(GPUVAddr gpu_addr, PageEntry page_entry, std::size_t size) {
- // TODO(bunnei): We should lock/unlock device regions. This currently causes issues due to
- // improper tracking, but should be fixed in the future.
-
- //// Unlock the old page
- // TryUnlockPage(page_table[PageEntryIndex(gpu_addr)], size);
-
- //// Lock the new page
- // TryLockPage(page_entry, size);
- auto& current_page = page_table[PageEntryIndex(gpu_addr)];
-
- if ((!current_page.IsValid() && page_entry.IsValid()) ||
- current_page.ToAddress() != page_entry.ToAddress()) {
- rasterizer->ModifyGPUMemory(gpu_addr, size);
+GPUVAddr MemoryManager::MapSparse(GPUVAddr gpu_addr, std::size_t size, bool is_big_pages) {
+ if (is_big_pages) [[likely]] {
+ return BigPageTableOp<EntryType::Reserved>(gpu_addr, 0, size, PTEKind::INVALID);
}
-
- current_page = page_entry;
+ return PageTableOp<EntryType::Reserved>(gpu_addr, 0, size, PTEKind::INVALID);
}
-std::optional<GPUVAddr> MemoryManager::FindFreeRange(std::size_t size, std::size_t align,
- bool start_32bit_address) const {
- if (!align) {
- align = page_size;
- } else {
- align = Common::AlignUp(align, page_size);
+void MemoryManager::Unmap(GPUVAddr gpu_addr, std::size_t size) {
+ if (size == 0) {
+ return;
}
+ const auto submapped_ranges = GetSubmappedRange(gpu_addr, size);
- u64 available_size{};
- GPUVAddr gpu_addr{start_32bit_address ? address_space_start_low : address_space_start};
- while (gpu_addr + available_size < address_space_size) {
- if (GetPageEntry(gpu_addr + available_size).IsUnmapped()) {
- available_size += page_size;
-
- if (available_size >= size) {
- return gpu_addr;
- }
- } else {
- gpu_addr += available_size + page_size;
- available_size = 0;
+ for (const auto& [map_addr, map_size] : submapped_ranges) {
+ // Flush and invalidate through the GPU interface, to be asynchronous if possible.
+ const std::optional<VAddr> cpu_addr = GpuToCpuAddress(map_addr);
+ ASSERT(cpu_addr);
- const auto remainder{gpu_addr % align};
- if (remainder) {
- gpu_addr = (gpu_addr - remainder) + align;
- }
- }
+ rasterizer->UnmapMemory(*cpu_addr, map_size);
}
- return std::nullopt;
+ BigPageTableOp<EntryType::Free>(gpu_addr, 0, size, PTEKind::INVALID);
+ PageTableOp<EntryType::Free>(gpu_addr, 0, size, PTEKind::INVALID);
}
std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) const {
- if (gpu_addr == 0) {
+ if (!IsWithinGPUAddressRange(gpu_addr)) [[unlikely]] {
return std::nullopt;
}
- const auto page_entry{GetPageEntry(gpu_addr)};
- if (!page_entry.IsValid()) {
- return std::nullopt;
+ if (GetEntry<true>(gpu_addr) != EntryType::Mapped) [[unlikely]] {
+ if (GetEntry<false>(gpu_addr) != EntryType::Mapped) {
+ return std::nullopt;
+ }
+
+ const VAddr cpu_addr_base = static_cast<VAddr>(page_table[PageEntryIndex<false>(gpu_addr)])
+ << cpu_page_bits;
+ return cpu_addr_base + (gpu_addr & page_mask);
}
- return page_entry.ToAddress() + (gpu_addr & page_mask);
+ const VAddr cpu_addr_base =
+ static_cast<VAddr>(big_page_table_cpu[PageEntryIndex<true>(gpu_addr)]) << cpu_page_bits;
+ return cpu_addr_base + (gpu_addr & big_page_mask);
}
std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr addr, std::size_t size) const {
@@ -189,7 +257,7 @@ std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr addr, std::size_t s
const size_t page_last{(addr + size + page_size - 1) >> page_bits};
while (page_index < page_last) {
const auto page_addr{GpuToCpuAddress(page_index << page_bits)};
- if (page_addr && *page_addr != 0) {
+ if (page_addr) {
return page_addr;
}
++page_index;
@@ -232,126 +300,298 @@ template void MemoryManager::Write<u32>(GPUVAddr addr, u32 data);
template void MemoryManager::Write<u64>(GPUVAddr addr, u64 data);
u8* MemoryManager::GetPointer(GPUVAddr gpu_addr) {
- if (!GetPageEntry(gpu_addr).IsValid()) {
- return {};
- }
-
const auto address{GpuToCpuAddress(gpu_addr)};
if (!address) {
return {};
}
- return system.Memory().GetPointer(*address);
+ return memory.GetPointer(*address);
}
const u8* MemoryManager::GetPointer(GPUVAddr gpu_addr) const {
- if (!GetPageEntry(gpu_addr).IsValid()) {
- return {};
- }
-
const auto address{GpuToCpuAddress(gpu_addr)};
if (!address) {
return {};
}
- return system.Memory().GetPointer(*address);
-}
-
-size_t MemoryManager::BytesToMapEnd(GPUVAddr gpu_addr) const noexcept {
- auto it = std::ranges::upper_bound(map_ranges, gpu_addr, {}, &MapRange::first);
- --it;
- return it->second - (gpu_addr - it->first);
-}
-
-void MemoryManager::ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size,
- bool is_safe) const {
+ return memory.GetPointer(*address);
+}
+
+#ifdef _MSC_VER // no need for gcc / clang but msvc's compiler is more conservative with inlining.
+#pragma inline_recursion(on)
+#endif
+
+template <bool is_big_pages, typename FuncMapped, typename FuncReserved, typename FuncUnmapped>
+inline void MemoryManager::MemoryOperation(GPUVAddr gpu_src_addr, std::size_t size,
+ FuncMapped&& func_mapped, FuncReserved&& func_reserved,
+ FuncUnmapped&& func_unmapped) const {
+ static constexpr bool BOOL_BREAK_MAPPED = std::is_same_v<FuncMapped, bool>;
+ static constexpr bool BOOL_BREAK_RESERVED = std::is_same_v<FuncReserved, bool>;
+ static constexpr bool BOOL_BREAK_UNMAPPED = std::is_same_v<FuncUnmapped, bool>;
+ u64 used_page_size;
+ u64 used_page_mask;
+ u64 used_page_bits;
+ if constexpr (is_big_pages) {
+ used_page_size = big_page_size;
+ used_page_mask = big_page_mask;
+ used_page_bits = big_page_bits;
+ } else {
+ used_page_size = page_size;
+ used_page_mask = page_mask;
+ used_page_bits = page_bits;
+ }
std::size_t remaining_size{size};
- std::size_t page_index{gpu_src_addr >> page_bits};
- std::size_t page_offset{gpu_src_addr & page_mask};
+ std::size_t page_index{gpu_src_addr >> used_page_bits};
+ std::size_t page_offset{gpu_src_addr & used_page_mask};
+ GPUVAddr current_address = gpu_src_addr;
while (remaining_size > 0) {
const std::size_t copy_amount{
- std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)};
- const auto page_addr{GpuToCpuAddress(page_index << page_bits)};
- if (page_addr && *page_addr != 0) {
- const auto src_addr{*page_addr + page_offset};
- if (is_safe) {
- // Flush must happen on the rasterizer interface, such that memory is always
- // synchronous when it is read (even when in asynchronous GPU mode).
- // Fixes Dead Cells title menu.
- rasterizer->FlushRegion(src_addr, copy_amount);
+ std::min(static_cast<std::size_t>(used_page_size) - page_offset, remaining_size)};
+ auto entry = GetEntry<is_big_pages>(current_address);
+ if (entry == EntryType::Mapped) [[likely]] {
+ if constexpr (BOOL_BREAK_MAPPED) {
+ if (func_mapped(page_index, page_offset, copy_amount)) {
+ return;
+ }
+ } else {
+ func_mapped(page_index, page_offset, copy_amount);
}
- system.Memory().ReadBlockUnsafe(src_addr, dest_buffer, copy_amount);
- } else {
- std::memset(dest_buffer, 0, copy_amount);
- }
+ } else if (entry == EntryType::Reserved) {
+ if constexpr (BOOL_BREAK_RESERVED) {
+ if (func_reserved(page_index, page_offset, copy_amount)) {
+ return;
+ }
+ } else {
+ func_reserved(page_index, page_offset, copy_amount);
+ }
+
+ } else [[unlikely]] {
+ if constexpr (BOOL_BREAK_UNMAPPED) {
+ if (func_unmapped(page_index, page_offset, copy_amount)) {
+ return;
+ }
+ } else {
+ func_unmapped(page_index, page_offset, copy_amount);
+ }
+ }
page_index++;
page_offset = 0;
- dest_buffer = static_cast<u8*>(dest_buffer) + copy_amount;
remaining_size -= copy_amount;
+ current_address += copy_amount;
}
}
+template <bool is_safe>
+void MemoryManager::ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer,
+ std::size_t size) const {
+ auto set_to_zero = [&]([[maybe_unused]] std::size_t page_index,
+ [[maybe_unused]] std::size_t offset, std::size_t copy_amount) {
+ std::memset(dest_buffer, 0, copy_amount);
+ dest_buffer = static_cast<u8*>(dest_buffer) + copy_amount;
+ };
+ auto mapped_normal = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset;
+ if constexpr (is_safe) {
+ rasterizer->FlushRegion(cpu_addr_base, copy_amount);
+ }
+ u8* physical = memory.GetPointer(cpu_addr_base);
+ std::memcpy(dest_buffer, physical, copy_amount);
+ dest_buffer = static_cast<u8*>(dest_buffer) + copy_amount;
+ };
+ auto mapped_big = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset;
+ if constexpr (is_safe) {
+ rasterizer->FlushRegion(cpu_addr_base, copy_amount);
+ }
+ if (!IsBigPageContinous(page_index)) [[unlikely]] {
+ memory.ReadBlockUnsafe(cpu_addr_base, dest_buffer, copy_amount);
+ } else {
+ u8* physical = memory.GetPointer(cpu_addr_base);
+ std::memcpy(dest_buffer, physical, copy_amount);
+ }
+ dest_buffer = static_cast<u8*>(dest_buffer) + copy_amount;
+ };
+ auto read_short_pages = [&](std::size_t page_index, std::size_t offset,
+ std::size_t copy_amount) {
+ GPUVAddr base = (page_index << big_page_bits) + offset;
+ MemoryOperation<false>(base, copy_amount, mapped_normal, set_to_zero, set_to_zero);
+ };
+ MemoryOperation<true>(gpu_src_addr, size, mapped_big, set_to_zero, read_short_pages);
+}
+
void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const {
- ReadBlockImpl(gpu_src_addr, dest_buffer, size, true);
+ ReadBlockImpl<true>(gpu_src_addr, dest_buffer, size);
}
void MemoryManager::ReadBlockUnsafe(GPUVAddr gpu_src_addr, void* dest_buffer,
const std::size_t size) const {
- ReadBlockImpl(gpu_src_addr, dest_buffer, size, false);
+ ReadBlockImpl<false>(gpu_src_addr, dest_buffer, size);
}
-void MemoryManager::WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size,
- bool is_safe) {
- std::size_t remaining_size{size};
- std::size_t page_index{gpu_dest_addr >> page_bits};
- std::size_t page_offset{gpu_dest_addr & page_mask};
-
- while (remaining_size > 0) {
- const std::size_t copy_amount{
- std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)};
- const auto page_addr{GpuToCpuAddress(page_index << page_bits)};
- if (page_addr && *page_addr != 0) {
- const auto dest_addr{*page_addr + page_offset};
-
- if (is_safe) {
- // Invalidate must happen on the rasterizer interface, such that memory is always
- // synchronous when it is written (even when in asynchronous GPU mode).
- rasterizer->InvalidateRegion(dest_addr, copy_amount);
- }
- system.Memory().WriteBlockUnsafe(dest_addr, src_buffer, copy_amount);
+template <bool is_safe>
+void MemoryManager::WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer,
+ std::size_t size) {
+ auto just_advance = [&]([[maybe_unused]] std::size_t page_index,
+ [[maybe_unused]] std::size_t offset, std::size_t copy_amount) {
+ src_buffer = static_cast<const u8*>(src_buffer) + copy_amount;
+ };
+ auto mapped_normal = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset;
+ if constexpr (is_safe) {
+ rasterizer->InvalidateRegion(cpu_addr_base, copy_amount);
}
-
- page_index++;
- page_offset = 0;
+ u8* physical = memory.GetPointer(cpu_addr_base);
+ std::memcpy(physical, src_buffer, copy_amount);
src_buffer = static_cast<const u8*>(src_buffer) + copy_amount;
- remaining_size -= copy_amount;
- }
+ };
+ auto mapped_big = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset;
+ if constexpr (is_safe) {
+ rasterizer->InvalidateRegion(cpu_addr_base, copy_amount);
+ }
+ if (!IsBigPageContinous(page_index)) [[unlikely]] {
+ memory.WriteBlockUnsafe(cpu_addr_base, src_buffer, copy_amount);
+ } else {
+ u8* physical = memory.GetPointer(cpu_addr_base);
+ std::memcpy(physical, src_buffer, copy_amount);
+ }
+ src_buffer = static_cast<const u8*>(src_buffer) + copy_amount;
+ };
+ auto write_short_pages = [&](std::size_t page_index, std::size_t offset,
+ std::size_t copy_amount) {
+ GPUVAddr base = (page_index << big_page_bits) + offset;
+ MemoryOperation<false>(base, copy_amount, mapped_normal, just_advance, just_advance);
+ };
+ MemoryOperation<true>(gpu_dest_addr, size, mapped_big, just_advance, write_short_pages);
}
void MemoryManager::WriteBlock(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size) {
- WriteBlockImpl(gpu_dest_addr, src_buffer, size, true);
+ WriteBlockImpl<true>(gpu_dest_addr, src_buffer, size);
}
void MemoryManager::WriteBlockUnsafe(GPUVAddr gpu_dest_addr, const void* src_buffer,
std::size_t size) {
- WriteBlockImpl(gpu_dest_addr, src_buffer, size, false);
+ WriteBlockImpl<false>(gpu_dest_addr, src_buffer, size);
}
void MemoryManager::FlushRegion(GPUVAddr gpu_addr, size_t size) const {
- size_t remaining_size{size};
- size_t page_index{gpu_addr >> page_bits};
- size_t page_offset{gpu_addr & page_mask};
- while (remaining_size > 0) {
- const size_t num_bytes{std::min(page_size - page_offset, remaining_size)};
- if (const auto page_addr{GpuToCpuAddress(page_index << page_bits)}; page_addr) {
- rasterizer->FlushRegion(*page_addr + page_offset, num_bytes);
+ auto do_nothing = [&]([[maybe_unused]] std::size_t page_index,
+ [[maybe_unused]] std::size_t offset,
+ [[maybe_unused]] std::size_t copy_amount) {};
+
+ auto mapped_normal = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset;
+ rasterizer->FlushRegion(cpu_addr_base, copy_amount);
+ };
+ auto mapped_big = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset;
+ rasterizer->FlushRegion(cpu_addr_base, copy_amount);
+ };
+ auto flush_short_pages = [&](std::size_t page_index, std::size_t offset,
+ std::size_t copy_amount) {
+ GPUVAddr base = (page_index << big_page_bits) + offset;
+ MemoryOperation<false>(base, copy_amount, mapped_normal, do_nothing, do_nothing);
+ };
+ MemoryOperation<true>(gpu_addr, size, mapped_big, do_nothing, flush_short_pages);
+}
+
+bool MemoryManager::IsMemoryDirty(GPUVAddr gpu_addr, size_t size) const {
+ bool result = false;
+ auto do_nothing = [&]([[maybe_unused]] std::size_t page_index,
+ [[maybe_unused]] std::size_t offset,
+ [[maybe_unused]] std::size_t copy_amount) { return false; };
+
+ auto mapped_normal = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset;
+ result |= rasterizer->MustFlushRegion(cpu_addr_base, copy_amount);
+ return result;
+ };
+ auto mapped_big = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset;
+ result |= rasterizer->MustFlushRegion(cpu_addr_base, copy_amount);
+ return result;
+ };
+ auto check_short_pages = [&](std::size_t page_index, std::size_t offset,
+ std::size_t copy_amount) {
+ GPUVAddr base = (page_index << big_page_bits) + offset;
+ MemoryOperation<false>(base, copy_amount, mapped_normal, do_nothing, do_nothing);
+ return result;
+ };
+ MemoryOperation<true>(gpu_addr, size, mapped_big, do_nothing, check_short_pages);
+ return result;
+}
+
+size_t MemoryManager::MaxContinousRange(GPUVAddr gpu_addr, size_t size) const {
+ std::optional<VAddr> old_page_addr{};
+ size_t range_so_far = 0;
+ bool result{false};
+ auto fail = [&]([[maybe_unused]] std::size_t page_index, [[maybe_unused]] std::size_t offset,
+ std::size_t copy_amount) {
+ result = true;
+ return true;
+ };
+ auto short_check = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset;
+ if (old_page_addr && *old_page_addr != cpu_addr_base) {
+ result = true;
+ return true;
}
- ++page_index;
- page_offset = 0;
- remaining_size -= num_bytes;
- }
+ range_so_far += copy_amount;
+ old_page_addr = {cpu_addr_base + copy_amount};
+ return false;
+ };
+ auto big_check = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset;
+ if (old_page_addr && *old_page_addr != cpu_addr_base) {
+ return true;
+ }
+ range_so_far += copy_amount;
+ old_page_addr = {cpu_addr_base + copy_amount};
+ return false;
+ };
+ auto check_short_pages = [&](std::size_t page_index, std::size_t offset,
+ std::size_t copy_amount) {
+ GPUVAddr base = (page_index << big_page_bits) + offset;
+ MemoryOperation<false>(base, copy_amount, short_check, fail, fail);
+ return result;
+ };
+ MemoryOperation<true>(gpu_addr, size, big_check, fail, check_short_pages);
+ return range_so_far;
+}
+
+void MemoryManager::InvalidateRegion(GPUVAddr gpu_addr, size_t size) const {
+ auto do_nothing = [&]([[maybe_unused]] std::size_t page_index,
+ [[maybe_unused]] std::size_t offset,
+ [[maybe_unused]] std::size_t copy_amount) {};
+
+ auto mapped_normal = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset;
+ rasterizer->InvalidateRegion(cpu_addr_base, copy_amount);
+ };
+ auto mapped_big = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset;
+ rasterizer->InvalidateRegion(cpu_addr_base, copy_amount);
+ };
+ auto invalidate_short_pages = [&](std::size_t page_index, std::size_t offset,
+ std::size_t copy_amount) {
+ GPUVAddr base = (page_index << big_page_bits) + offset;
+ MemoryOperation<false>(base, copy_amount, mapped_normal, do_nothing, do_nothing);
+ };
+ MemoryOperation<true>(gpu_addr, size, mapped_big, do_nothing, invalidate_short_pages);
}
void MemoryManager::CopyBlock(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std::size_t size) {
@@ -365,87 +605,134 @@ void MemoryManager::CopyBlock(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std
}
bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) const {
- const auto cpu_addr{GpuToCpuAddress(gpu_addr)};
- if (!cpu_addr) {
+ if (GetEntry<true>(gpu_addr) == EntryType::Mapped) [[likely]] {
+ size_t page_index = gpu_addr >> big_page_bits;
+ if (IsBigPageContinous(page_index)) [[likely]] {
+ const std::size_t page{(page_index & big_page_mask) + size};
+ return page <= big_page_size;
+ }
+ const std::size_t page{(gpu_addr & Core::Memory::YUZU_PAGEMASK) + size};
+ return page <= Core::Memory::YUZU_PAGESIZE;
+ }
+ if (GetEntry<false>(gpu_addr) != EntryType::Mapped) {
return false;
}
- const std::size_t page{(*cpu_addr & Core::Memory::YUZU_PAGEMASK) + size};
+ const std::size_t page{(gpu_addr & Core::Memory::YUZU_PAGEMASK) + size};
return page <= Core::Memory::YUZU_PAGESIZE;
}
bool MemoryManager::IsContinousRange(GPUVAddr gpu_addr, std::size_t size) const {
- size_t page_index{gpu_addr >> page_bits};
- const size_t page_last{(gpu_addr + size + page_size - 1) >> page_bits};
std::optional<VAddr> old_page_addr{};
- while (page_index != page_last) {
- const auto page_addr{GpuToCpuAddress(page_index << page_bits)};
- if (!page_addr || *page_addr == 0) {
- return false;
+ bool result{true};
+ auto fail = [&]([[maybe_unused]] std::size_t page_index, [[maybe_unused]] std::size_t offset,
+ std::size_t copy_amount) {
+ result = false;
+ return true;
+ };
+ auto short_check = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset;
+ if (old_page_addr && *old_page_addr != cpu_addr_base) {
+ result = false;
+ return true;
}
- if (old_page_addr) {
- if (*old_page_addr + page_size != *page_addr) {
- return false;
- }
+ old_page_addr = {cpu_addr_base + copy_amount};
+ return false;
+ };
+ auto big_check = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset;
+ if (old_page_addr && *old_page_addr != cpu_addr_base) {
+ result = false;
+ return true;
}
- old_page_addr = page_addr;
- ++page_index;
- }
- return true;
+ old_page_addr = {cpu_addr_base + copy_amount};
+ return false;
+ };
+ auto check_short_pages = [&](std::size_t page_index, std::size_t offset,
+ std::size_t copy_amount) {
+ GPUVAddr base = (page_index << big_page_bits) + offset;
+ MemoryOperation<false>(base, copy_amount, short_check, fail, fail);
+ return !result;
+ };
+ MemoryOperation<true>(gpu_addr, size, big_check, fail, check_short_pages);
+ return result;
}
bool MemoryManager::IsFullyMappedRange(GPUVAddr gpu_addr, std::size_t size) const {
- size_t page_index{gpu_addr >> page_bits};
- const size_t page_last{(gpu_addr + size + page_size - 1) >> page_bits};
- while (page_index < page_last) {
- if (!page_table[page_index].IsValid() || page_table[page_index].ToAddress() == 0) {
- return false;
- }
- ++page_index;
- }
- return true;
+ bool result{true};
+ auto fail = [&]([[maybe_unused]] std::size_t page_index, [[maybe_unused]] std::size_t offset,
+ [[maybe_unused]] std::size_t copy_amount) {
+ result = false;
+ return true;
+ };
+ auto pass = [&]([[maybe_unused]] std::size_t page_index, [[maybe_unused]] std::size_t offset,
+ [[maybe_unused]] std::size_t copy_amount) { return false; };
+ auto check_short_pages = [&](std::size_t page_index, std::size_t offset,
+ std::size_t copy_amount) {
+ GPUVAddr base = (page_index << big_page_bits) + offset;
+ MemoryOperation<false>(base, copy_amount, pass, pass, fail);
+ return !result;
+ };
+ MemoryOperation<true>(gpu_addr, size, pass, fail, check_short_pages);
+ return result;
}
std::vector<std::pair<GPUVAddr, std::size_t>> MemoryManager::GetSubmappedRange(
GPUVAddr gpu_addr, std::size_t size) const {
std::vector<std::pair<GPUVAddr, std::size_t>> result{};
- size_t page_index{gpu_addr >> page_bits};
- size_t remaining_size{size};
- size_t page_offset{gpu_addr & page_mask};
std::optional<std::pair<GPUVAddr, std::size_t>> last_segment{};
std::optional<VAddr> old_page_addr{};
- const auto extend_size = [&last_segment, &page_index, &page_offset](std::size_t bytes) {
- if (!last_segment) {
- const GPUVAddr new_base_addr = (page_index << page_bits) + page_offset;
- last_segment = {new_base_addr, bytes};
- } else {
- last_segment->second += bytes;
- }
- };
- const auto split = [&last_segment, &result] {
+ const auto split = [&last_segment, &result]([[maybe_unused]] std::size_t page_index,
+ [[maybe_unused]] std::size_t offset,
+ [[maybe_unused]] std::size_t copy_amount) {
if (last_segment) {
result.push_back(*last_segment);
last_segment = std::nullopt;
}
};
- while (remaining_size > 0) {
- const size_t num_bytes{std::min(page_size - page_offset, remaining_size)};
- const auto page_addr{GpuToCpuAddress(page_index << page_bits)};
- if (!page_addr || *page_addr == 0) {
- split();
- } else if (old_page_addr) {
- if (*old_page_addr + page_size != *page_addr) {
- split();
+ const auto extend_size_big = [this, &split, &old_page_addr,
+ &last_segment](std::size_t page_index, std::size_t offset,
+ std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(big_page_table_cpu[page_index]) << cpu_page_bits) + offset;
+ if (old_page_addr) {
+ if (*old_page_addr != cpu_addr_base) {
+ split(0, 0, 0);
+ }
+ }
+ old_page_addr = {cpu_addr_base + copy_amount};
+ if (!last_segment) {
+ const GPUVAddr new_base_addr = (page_index << big_page_bits) + offset;
+ last_segment = {new_base_addr, copy_amount};
+ } else {
+ last_segment->second += copy_amount;
+ }
+ };
+ const auto extend_size_short = [this, &split, &old_page_addr,
+ &last_segment](std::size_t page_index, std::size_t offset,
+ std::size_t copy_amount) {
+ const VAddr cpu_addr_base =
+ (static_cast<VAddr>(page_table[page_index]) << cpu_page_bits) + offset;
+ if (old_page_addr) {
+ if (*old_page_addr != cpu_addr_base) {
+ split(0, 0, 0);
}
- extend_size(num_bytes);
+ }
+ old_page_addr = {cpu_addr_base + copy_amount};
+ if (!last_segment) {
+ const GPUVAddr new_base_addr = (page_index << page_bits) + offset;
+ last_segment = {new_base_addr, copy_amount};
} else {
- extend_size(num_bytes);
+ last_segment->second += copy_amount;
}
- ++page_index;
- page_offset = 0;
- remaining_size -= num_bytes;
- old_page_addr = page_addr;
- }
- split();
+ };
+ auto do_short_pages = [&](std::size_t page_index, std::size_t offset, std::size_t copy_amount) {
+ GPUVAddr base = (page_index << big_page_bits) + offset;
+ MemoryOperation<false>(base, copy_amount, extend_size_short, split, split);
+ };
+ MemoryOperation<true>(gpu_addr, size, extend_size_big, split, do_short_pages);
+ split(0, 0, 0);
return result;
}
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h
index 74f9ce175..ab4bc9ec6 100644
--- a/src/video_core/memory_manager.h
+++ b/src/video_core/memory_manager.h
@@ -3,73 +3,40 @@
#pragma once
+#include <atomic>
#include <map>
#include <optional>
#include <vector>
#include "common/common_types.h"
+#include "common/multi_level_page_table.h"
+#include "common/virtual_buffer.h"
+#include "video_core/pte_kind.h"
namespace VideoCore {
class RasterizerInterface;
}
namespace Core {
+class DeviceMemory;
+namespace Memory {
+class Memory;
+} // namespace Memory
class System;
-}
+} // namespace Core
namespace Tegra {
-class PageEntry final {
-public:
- enum class State : u32 {
- Unmapped = static_cast<u32>(-1),
- Allocated = static_cast<u32>(-2),
- };
-
- constexpr PageEntry() = default;
- constexpr PageEntry(State state_) : state{state_} {}
- constexpr PageEntry(VAddr addr) : state{static_cast<State>(addr >> ShiftBits)} {}
-
- [[nodiscard]] constexpr bool IsUnmapped() const {
- return state == State::Unmapped;
- }
-
- [[nodiscard]] constexpr bool IsAllocated() const {
- return state == State::Allocated;
- }
-
- [[nodiscard]] constexpr bool IsValid() const {
- return !IsUnmapped() && !IsAllocated();
- }
-
- [[nodiscard]] constexpr VAddr ToAddress() const {
- if (!IsValid()) {
- return {};
- }
-
- return static_cast<VAddr>(state) << ShiftBits;
- }
-
- [[nodiscard]] constexpr PageEntry operator+(u64 offset) const {
- // If this is a reserved value, offsets do not apply
- if (!IsValid()) {
- return *this;
- }
- return PageEntry{(static_cast<VAddr>(state) << ShiftBits) + offset};
- }
-
-private:
- static constexpr std::size_t ShiftBits{12};
-
- State state{State::Unmapped};
-};
-static_assert(sizeof(PageEntry) == 4, "PageEntry is too large");
-
class MemoryManager final {
public:
- explicit MemoryManager(Core::System& system_);
+ explicit MemoryManager(Core::System& system_, u64 address_space_bits_ = 40,
+ u64 big_page_bits_ = 16, u64 page_bits_ = 12);
~MemoryManager();
+ size_t GetID() const {
+ return unique_identifier;
+ }
+
/// Binds a renderer to the memory manager.
void BindRasterizer(VideoCore::RasterizerInterface* rasterizer);
@@ -86,9 +53,6 @@ public:
[[nodiscard]] u8* GetPointer(GPUVAddr addr);
[[nodiscard]] const u8* GetPointer(GPUVAddr addr) const;
- /// Returns the number of bytes until the end of the memory map containing the given GPU address
- [[nodiscard]] size_t BytesToMapEnd(GPUVAddr gpu_addr) const noexcept;
-
/**
* ReadBlock and WriteBlock are full read and write operations over virtual
* GPU Memory. It's important to use these when GPU memory may not be continuous
@@ -135,54 +99,109 @@ public:
std::vector<std::pair<GPUVAddr, std::size_t>> GetSubmappedRange(GPUVAddr gpu_addr,
std::size_t size) const;
- [[nodiscard]] GPUVAddr Map(VAddr cpu_addr, GPUVAddr gpu_addr, std::size_t size);
- [[nodiscard]] GPUVAddr MapAllocate(VAddr cpu_addr, std::size_t size, std::size_t align);
- [[nodiscard]] GPUVAddr MapAllocate32(VAddr cpu_addr, std::size_t size);
- [[nodiscard]] std::optional<GPUVAddr> AllocateFixed(GPUVAddr gpu_addr, std::size_t size);
- [[nodiscard]] GPUVAddr Allocate(std::size_t size, std::size_t align);
+ GPUVAddr Map(GPUVAddr gpu_addr, VAddr cpu_addr, std::size_t size,
+ PTEKind kind = PTEKind::INVALID, bool is_big_pages = true);
+ GPUVAddr MapSparse(GPUVAddr gpu_addr, std::size_t size, bool is_big_pages = true);
void Unmap(GPUVAddr gpu_addr, std::size_t size);
void FlushRegion(GPUVAddr gpu_addr, size_t size) const;
+ void InvalidateRegion(GPUVAddr gpu_addr, size_t size) const;
+
+ bool IsMemoryDirty(GPUVAddr gpu_addr, size_t size) const;
+
+ size_t MaxContinousRange(GPUVAddr gpu_addr, size_t size) const;
+
+ bool IsWithinGPUAddressRange(GPUVAddr gpu_addr) const {
+ return gpu_addr < address_space_size;
+ }
+
+ PTEKind GetPageKind(GPUVAddr gpu_addr) const;
+
private:
- [[nodiscard]] PageEntry GetPageEntry(GPUVAddr gpu_addr) const;
- void SetPageEntry(GPUVAddr gpu_addr, PageEntry page_entry, std::size_t size = page_size);
- GPUVAddr UpdateRange(GPUVAddr gpu_addr, PageEntry page_entry, std::size_t size);
- [[nodiscard]] std::optional<GPUVAddr> FindFreeRange(std::size_t size, std::size_t align,
- bool start_32bit_address = false) const;
-
- void TryLockPage(PageEntry page_entry, std::size_t size);
- void TryUnlockPage(PageEntry page_entry, std::size_t size);
-
- void ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size,
- bool is_safe) const;
- void WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size,
- bool is_safe);
-
- [[nodiscard]] static constexpr std::size_t PageEntryIndex(GPUVAddr gpu_addr) {
- return (gpu_addr >> page_bits) & page_table_mask;
+ template <bool is_big_pages, typename FuncMapped, typename FuncReserved, typename FuncUnmapped>
+ inline void MemoryOperation(GPUVAddr gpu_src_addr, std::size_t size, FuncMapped&& func_mapped,
+ FuncReserved&& func_reserved, FuncUnmapped&& func_unmapped) const;
+
+ template <bool is_safe>
+ void ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const;
+
+ template <bool is_safe>
+ void WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size);
+
+ template <bool is_big_page>
+ [[nodiscard]] std::size_t PageEntryIndex(GPUVAddr gpu_addr) const {
+ if constexpr (is_big_page) {
+ return (gpu_addr >> big_page_bits) & big_page_table_mask;
+ } else {
+ return (gpu_addr >> page_bits) & page_table_mask;
+ }
}
- static constexpr u64 address_space_size = 1ULL << 40;
- static constexpr u64 address_space_start = 1ULL << 32;
- static constexpr u64 address_space_start_low = 1ULL << 16;
- static constexpr u64 page_bits{16};
- static constexpr u64 page_size{1 << page_bits};
- static constexpr u64 page_mask{page_size - 1};
- static constexpr u64 page_table_bits{24};
- static constexpr u64 page_table_size{1 << page_table_bits};
- static constexpr u64 page_table_mask{page_table_size - 1};
+ inline bool IsBigPageContinous(size_t big_page_index) const;
+ inline void SetBigPageContinous(size_t big_page_index, bool value);
Core::System& system;
+ Core::Memory::Memory& memory;
+ Core::DeviceMemory& device_memory;
+
+ const u64 address_space_bits;
+ const u64 page_bits;
+ u64 address_space_size;
+ u64 page_size;
+ u64 page_mask;
+ u64 page_table_mask;
+ static constexpr u64 cpu_page_bits{12};
+
+ const u64 big_page_bits;
+ u64 big_page_size;
+ u64 big_page_mask;
+ u64 big_page_table_mask;
VideoCore::RasterizerInterface* rasterizer = nullptr;
- std::vector<PageEntry> page_table;
+ enum class EntryType : u64 {
+ Free = 0,
+ Reserved = 1,
+ Mapped = 2,
+ };
+
+ std::vector<u64> entries;
+ std::vector<u64> big_entries;
+
+ template <EntryType entry_type>
+ GPUVAddr PageTableOp(GPUVAddr gpu_addr, [[maybe_unused]] VAddr cpu_addr, size_t size,
+ PTEKind kind);
+
+ template <EntryType entry_type>
+ GPUVAddr BigPageTableOp(GPUVAddr gpu_addr, [[maybe_unused]] VAddr cpu_addr, size_t size,
+ PTEKind kind);
+
+ template <bool is_big_page>
+ inline EntryType GetEntry(size_t position) const;
+
+ template <bool is_big_page>
+ inline void SetEntry(size_t position, EntryType entry);
+
+ std::vector<std::array<PTEKind, 32>> kinds;
+ std::vector<std::array<PTEKind, 32>> big_kinds;
+
+ template <bool is_big_page>
+ inline PTEKind GetKind(size_t position) const;
+
+ template <bool is_big_page>
+ inline void SetKind(size_t position, PTEKind kind);
+
+ Common::MultiLevelPageTable<u32> page_table;
+ Common::VirtualBuffer<u32> big_page_table_cpu;
+
+ std::vector<u64> big_page_continous;
+
+ constexpr static size_t continous_bits = 64;
- using MapRange = std::pair<GPUVAddr, size_t>;
- std::vector<MapRange> map_ranges;
+ const size_t unique_identifier;
- std::vector<std::pair<VAddr, std::size_t>> cache_invalidate_queue;
+ static std::atomic<size_t> unique_identifier_generator;
};
} // namespace Tegra
diff --git a/src/video_core/pte_kind.h b/src/video_core/pte_kind.h
new file mode 100644
index 000000000..591d7214b
--- /dev/null
+++ b/src/video_core/pte_kind.h
@@ -0,0 +1,264 @@
+// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "common/common_types.h"
+
+namespace Tegra {
+
+// https://github.com/NVIDIA/open-gpu-doc/blob/master/manuals/volta/gv100/dev_mmu.ref.txt
+enum class PTEKind : u8 {
+ INVALID = 0xff,
+ PITCH = 0x00,
+ Z16 = 0x01,
+ Z16_2C = 0x02,
+ Z16_MS2_2C = 0x03,
+ Z16_MS4_2C = 0x04,
+ Z16_MS8_2C = 0x05,
+ Z16_MS16_2C = 0x06,
+ Z16_2Z = 0x07,
+ Z16_MS2_2Z = 0x08,
+ Z16_MS4_2Z = 0x09,
+ Z16_MS8_2Z = 0x0a,
+ Z16_MS16_2Z = 0x0b,
+ Z16_2CZ = 0x36,
+ Z16_MS2_2CZ = 0x37,
+ Z16_MS4_2CZ = 0x38,
+ Z16_MS8_2CZ = 0x39,
+ Z16_MS16_2CZ = 0x5f,
+ Z16_4CZ = 0x0c,
+ Z16_MS2_4CZ = 0x0d,
+ Z16_MS4_4CZ = 0x0e,
+ Z16_MS8_4CZ = 0x0f,
+ Z16_MS16_4CZ = 0x10,
+ S8Z24 = 0x11,
+ S8Z24_1Z = 0x12,
+ S8Z24_MS2_1Z = 0x13,
+ S8Z24_MS4_1Z = 0x14,
+ S8Z24_MS8_1Z = 0x15,
+ S8Z24_MS16_1Z = 0x16,
+ S8Z24_2CZ = 0x17,
+ S8Z24_MS2_2CZ = 0x18,
+ S8Z24_MS4_2CZ = 0x19,
+ S8Z24_MS8_2CZ = 0x1a,
+ S8Z24_MS16_2CZ = 0x1b,
+ S8Z24_2CS = 0x1c,
+ S8Z24_MS2_2CS = 0x1d,
+ S8Z24_MS4_2CS = 0x1e,
+ S8Z24_MS8_2CS = 0x1f,
+ S8Z24_MS16_2CS = 0x20,
+ S8Z24_4CSZV = 0x21,
+ S8Z24_MS2_4CSZV = 0x22,
+ S8Z24_MS4_4CSZV = 0x23,
+ S8Z24_MS8_4CSZV = 0x24,
+ S8Z24_MS16_4CSZV = 0x25,
+ V8Z24_MS4_VC12 = 0x26,
+ V8Z24_MS4_VC4 = 0x27,
+ V8Z24_MS8_VC8 = 0x28,
+ V8Z24_MS8_VC24 = 0x29,
+ V8Z24_MS4_VC12_1ZV = 0x2e,
+ V8Z24_MS4_VC4_1ZV = 0x2f,
+ V8Z24_MS8_VC8_1ZV = 0x30,
+ V8Z24_MS8_VC24_1ZV = 0x31,
+ V8Z24_MS4_VC12_2CS = 0x32,
+ V8Z24_MS4_VC4_2CS = 0x33,
+ V8Z24_MS8_VC8_2CS = 0x34,
+ V8Z24_MS8_VC24_2CS = 0x35,
+ V8Z24_MS4_VC12_2CZV = 0x3a,
+ V8Z24_MS4_VC4_2CZV = 0x3b,
+ V8Z24_MS8_VC8_2CZV = 0x3c,
+ V8Z24_MS8_VC24_2CZV = 0x3d,
+ V8Z24_MS4_VC12_2ZV = 0x3e,
+ V8Z24_MS4_VC4_2ZV = 0x3f,
+ V8Z24_MS8_VC8_2ZV = 0x40,
+ V8Z24_MS8_VC24_2ZV = 0x41,
+ V8Z24_MS4_VC12_4CSZV = 0x42,
+ V8Z24_MS4_VC4_4CSZV = 0x43,
+ V8Z24_MS8_VC8_4CSZV = 0x44,
+ V8Z24_MS8_VC24_4CSZV = 0x45,
+ Z24S8 = 0x46,
+ Z24S8_1Z = 0x47,
+ Z24S8_MS2_1Z = 0x48,
+ Z24S8_MS4_1Z = 0x49,
+ Z24S8_MS8_1Z = 0x4a,
+ Z24S8_MS16_1Z = 0x4b,
+ Z24S8_2CS = 0x4c,
+ Z24S8_MS2_2CS = 0x4d,
+ Z24S8_MS4_2CS = 0x4e,
+ Z24S8_MS8_2CS = 0x4f,
+ Z24S8_MS16_2CS = 0x50,
+ Z24S8_2CZ = 0x51,
+ Z24S8_MS2_2CZ = 0x52,
+ Z24S8_MS4_2CZ = 0x53,
+ Z24S8_MS8_2CZ = 0x54,
+ Z24S8_MS16_2CZ = 0x55,
+ Z24S8_4CSZV = 0x56,
+ Z24S8_MS2_4CSZV = 0x57,
+ Z24S8_MS4_4CSZV = 0x58,
+ Z24S8_MS8_4CSZV = 0x59,
+ Z24S8_MS16_4CSZV = 0x5a,
+ Z24V8_MS4_VC12 = 0x5b,
+ Z24V8_MS4_VC4 = 0x5c,
+ Z24V8_MS8_VC8 = 0x5d,
+ Z24V8_MS8_VC24 = 0x5e,
+ YUV_B8C1_2Y = 0x60,
+ YUV_B8C2_2Y = 0x61,
+ YUV_B10C1_2Y = 0x62,
+ YUV_B10C2_2Y = 0x6b,
+ YUV_B12C1_2Y = 0x6c,
+ YUV_B12C2_2Y = 0x6d,
+ Z24V8_MS4_VC12_1ZV = 0x63,
+ Z24V8_MS4_VC4_1ZV = 0x64,
+ Z24V8_MS8_VC8_1ZV = 0x65,
+ Z24V8_MS8_VC24_1ZV = 0x66,
+ Z24V8_MS4_VC12_2CS = 0x67,
+ Z24V8_MS4_VC4_2CS = 0x68,
+ Z24V8_MS8_VC8_2CS = 0x69,
+ Z24V8_MS8_VC24_2CS = 0x6a,
+ Z24V8_MS4_VC12_2CZV = 0x6f,
+ Z24V8_MS4_VC4_2CZV = 0x70,
+ Z24V8_MS8_VC8_2CZV = 0x71,
+ Z24V8_MS8_VC24_2CZV = 0x72,
+ Z24V8_MS4_VC12_2ZV = 0x73,
+ Z24V8_MS4_VC4_2ZV = 0x74,
+ Z24V8_MS8_VC8_2ZV = 0x75,
+ Z24V8_MS8_VC24_2ZV = 0x76,
+ Z24V8_MS4_VC12_4CSZV = 0x77,
+ Z24V8_MS4_VC4_4CSZV = 0x78,
+ Z24V8_MS8_VC8_4CSZV = 0x79,
+ Z24V8_MS8_VC24_4CSZV = 0x7a,
+ ZF32 = 0x7b,
+ ZF32_1Z = 0x7c,
+ ZF32_MS2_1Z = 0x7d,
+ ZF32_MS4_1Z = 0x7e,
+ ZF32_MS8_1Z = 0x7f,
+ ZF32_MS16_1Z = 0x80,
+ ZF32_2CS = 0x81,
+ ZF32_MS2_2CS = 0x82,
+ ZF32_MS4_2CS = 0x83,
+ ZF32_MS8_2CS = 0x84,
+ ZF32_MS16_2CS = 0x85,
+ ZF32_2CZ = 0x86,
+ ZF32_MS2_2CZ = 0x87,
+ ZF32_MS4_2CZ = 0x88,
+ ZF32_MS8_2CZ = 0x89,
+ ZF32_MS16_2CZ = 0x8a,
+ X8Z24_X16V8S8_MS4_VC12 = 0x8b,
+ X8Z24_X16V8S8_MS4_VC4 = 0x8c,
+ X8Z24_X16V8S8_MS8_VC8 = 0x8d,
+ X8Z24_X16V8S8_MS8_VC24 = 0x8e,
+ X8Z24_X16V8S8_MS4_VC12_1CS = 0x8f,
+ X8Z24_X16V8S8_MS4_VC4_1CS = 0x90,
+ X8Z24_X16V8S8_MS8_VC8_1CS = 0x91,
+ X8Z24_X16V8S8_MS8_VC24_1CS = 0x92,
+ X8Z24_X16V8S8_MS4_VC12_1ZV = 0x97,
+ X8Z24_X16V8S8_MS4_VC4_1ZV = 0x98,
+ X8Z24_X16V8S8_MS8_VC8_1ZV = 0x99,
+ X8Z24_X16V8S8_MS8_VC24_1ZV = 0x9a,
+ X8Z24_X16V8S8_MS4_VC12_1CZV = 0x9b,
+ X8Z24_X16V8S8_MS4_VC4_1CZV = 0x9c,
+ X8Z24_X16V8S8_MS8_VC8_1CZV = 0x9d,
+ X8Z24_X16V8S8_MS8_VC24_1CZV = 0x9e,
+ X8Z24_X16V8S8_MS4_VC12_2CS = 0x9f,
+ X8Z24_X16V8S8_MS4_VC4_2CS = 0xa0,
+ X8Z24_X16V8S8_MS8_VC8_2CS = 0xa1,
+ X8Z24_X16V8S8_MS8_VC24_2CS = 0xa2,
+ X8Z24_X16V8S8_MS4_VC12_2CSZV = 0xa3,
+ X8Z24_X16V8S8_MS4_VC4_2CSZV = 0xa4,
+ X8Z24_X16V8S8_MS8_VC8_2CSZV = 0xa5,
+ X8Z24_X16V8S8_MS8_VC24_2CSZV = 0xa6,
+ ZF32_X16V8S8_MS4_VC12 = 0xa7,
+ ZF32_X16V8S8_MS4_VC4 = 0xa8,
+ ZF32_X16V8S8_MS8_VC8 = 0xa9,
+ ZF32_X16V8S8_MS8_VC24 = 0xaa,
+ ZF32_X16V8S8_MS4_VC12_1CS = 0xab,
+ ZF32_X16V8S8_MS4_VC4_1CS = 0xac,
+ ZF32_X16V8S8_MS8_VC8_1CS = 0xad,
+ ZF32_X16V8S8_MS8_VC24_1CS = 0xae,
+ ZF32_X16V8S8_MS4_VC12_1ZV = 0xb3,
+ ZF32_X16V8S8_MS4_VC4_1ZV = 0xb4,
+ ZF32_X16V8S8_MS8_VC8_1ZV = 0xb5,
+ ZF32_X16V8S8_MS8_VC24_1ZV = 0xb6,
+ ZF32_X16V8S8_MS4_VC12_1CZV = 0xb7,
+ ZF32_X16V8S8_MS4_VC4_1CZV = 0xb8,
+ ZF32_X16V8S8_MS8_VC8_1CZV = 0xb9,
+ ZF32_X16V8S8_MS8_VC24_1CZV = 0xba,
+ ZF32_X16V8S8_MS4_VC12_2CS = 0xbb,
+ ZF32_X16V8S8_MS4_VC4_2CS = 0xbc,
+ ZF32_X16V8S8_MS8_VC8_2CS = 0xbd,
+ ZF32_X16V8S8_MS8_VC24_2CS = 0xbe,
+ ZF32_X16V8S8_MS4_VC12_2CSZV = 0xbf,
+ ZF32_X16V8S8_MS4_VC4_2CSZV = 0xc0,
+ ZF32_X16V8S8_MS8_VC8_2CSZV = 0xc1,
+ ZF32_X16V8S8_MS8_VC24_2CSZV = 0xc2,
+ ZF32_X24S8 = 0xc3,
+ ZF32_X24S8_1CS = 0xc4,
+ ZF32_X24S8_MS2_1CS = 0xc5,
+ ZF32_X24S8_MS4_1CS = 0xc6,
+ ZF32_X24S8_MS8_1CS = 0xc7,
+ ZF32_X24S8_MS16_1CS = 0xc8,
+ ZF32_X24S8_2CSZV = 0xce,
+ ZF32_X24S8_MS2_2CSZV = 0xcf,
+ ZF32_X24S8_MS4_2CSZV = 0xd0,
+ ZF32_X24S8_MS8_2CSZV = 0xd1,
+ ZF32_X24S8_MS16_2CSZV = 0xd2,
+ ZF32_X24S8_2CS = 0xd3,
+ ZF32_X24S8_MS2_2CS = 0xd4,
+ ZF32_X24S8_MS4_2CS = 0xd5,
+ ZF32_X24S8_MS8_2CS = 0xd6,
+ ZF32_X24S8_MS16_2CS = 0xd7,
+ S8 = 0x2a,
+ S8_2S = 0x2b,
+ GENERIC_16BX2 = 0xfe,
+ C32_2C = 0xd8,
+ C32_2CBR = 0xd9,
+ C32_2CBA = 0xda,
+ C32_2CRA = 0xdb,
+ C32_2BRA = 0xdc,
+ C32_MS2_2C = 0xdd,
+ C32_MS2_2CBR = 0xde,
+ C32_MS2_4CBRA = 0xcc,
+ C32_MS4_2C = 0xdf,
+ C32_MS4_2CBR = 0xe0,
+ C32_MS4_2CBA = 0xe1,
+ C32_MS4_2CRA = 0xe2,
+ C32_MS4_2BRA = 0xe3,
+ C32_MS4_4CBRA = 0x2c,
+ C32_MS8_MS16_2C = 0xe4,
+ C32_MS8_MS16_2CRA = 0xe5,
+ C64_2C = 0xe6,
+ C64_2CBR = 0xe7,
+ C64_2CBA = 0xe8,
+ C64_2CRA = 0xe9,
+ C64_2BRA = 0xea,
+ C64_MS2_2C = 0xeb,
+ C64_MS2_2CBR = 0xec,
+ C64_MS2_4CBRA = 0xcd,
+ C64_MS4_2C = 0xed,
+ C64_MS4_2CBR = 0xee,
+ C64_MS4_2CBA = 0xef,
+ C64_MS4_2CRA = 0xf0,
+ C64_MS4_2BRA = 0xf1,
+ C64_MS4_4CBRA = 0x2d,
+ C64_MS8_MS16_2C = 0xf2,
+ C64_MS8_MS16_2CRA = 0xf3,
+ C128_2C = 0xf4,
+ C128_2CR = 0xf5,
+ C128_MS2_2C = 0xf6,
+ C128_MS2_2CR = 0xf7,
+ C128_MS4_2C = 0xf8,
+ C128_MS4_2CR = 0xf9,
+ C128_MS8_MS16_2C = 0xfa,
+ C128_MS8_MS16_2CR = 0xfb,
+ X8C24 = 0xfc,
+ PITCH_NO_SWIZZLE = 0xfd,
+ SMSKED_MESSAGE = 0xca,
+ SMHOST_MESSAGE = 0xcb,
+};
+
+constexpr bool IsPitchKind(PTEKind kind) {
+ return kind == PTEKind::PITCH || kind == PTEKind::PITCH_NO_SWIZZLE;
+}
+
+} // namespace Tegra
diff --git a/src/video_core/query_cache.h b/src/video_core/query_cache.h
index 889b606b3..00ce53e3e 100644
--- a/src/video_core/query_cache.h
+++ b/src/video_core/query_cache.h
@@ -17,6 +17,7 @@
#include "common/assert.h"
#include "common/settings.h"
+#include "video_core/control/channel_state_cache.h"
#include "video_core/engines/maxwell_3d.h"
#include "video_core/memory_manager.h"
#include "video_core/rasterizer_interface.h"
@@ -90,13 +91,10 @@ private:
};
template <class QueryCache, class CachedQuery, class CounterStream, class HostCounter>
-class QueryCacheBase {
+class QueryCacheBase : public VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo> {
public:
- explicit QueryCacheBase(VideoCore::RasterizerInterface& rasterizer_,
- Tegra::Engines::Maxwell3D& maxwell3d_,
- Tegra::MemoryManager& gpu_memory_)
- : rasterizer{rasterizer_}, maxwell3d{maxwell3d_},
- gpu_memory{gpu_memory_}, streams{{CounterStream{static_cast<QueryCache&>(*this),
+ explicit QueryCacheBase(VideoCore::RasterizerInterface& rasterizer_)
+ : rasterizer{rasterizer_}, streams{{CounterStream{static_cast<QueryCache&>(*this),
VideoCore::QueryType::SamplesPassed}}} {}
void InvalidateRegion(VAddr addr, std::size_t size) {
@@ -117,13 +115,13 @@ public:
*/
void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) {
std::unique_lock lock{mutex};
- const std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
+ const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
ASSERT(cpu_addr);
CachedQuery* query = TryGet(*cpu_addr);
if (!query) {
ASSERT_OR_EXECUTE(cpu_addr, return;);
- u8* const host_ptr = gpu_memory.GetPointer(gpu_addr);
+ u8* const host_ptr = gpu_memory->GetPointer(gpu_addr);
query = Register(type, *cpu_addr, host_ptr, timestamp.has_value());
}
@@ -137,8 +135,10 @@ public:
/// Updates counters from GPU state. Expected to be called once per draw, clear or dispatch.
void UpdateCounters() {
std::unique_lock lock{mutex};
- const auto& regs = maxwell3d.regs;
- Stream(VideoCore::QueryType::SamplesPassed).Update(regs.samplecnt_enable);
+ if (maxwell3d) {
+ const auto& regs = maxwell3d->regs;
+ Stream(VideoCore::QueryType::SamplesPassed).Update(regs.zpass_pixel_count_enable);
+ }
}
/// Resets a counter to zero. It doesn't disable the query after resetting.
@@ -264,8 +264,6 @@ private:
static constexpr unsigned YUZU_PAGEBITS = 12;
VideoCore::RasterizerInterface& rasterizer;
- Tegra::Engines::Maxwell3D& maxwell3d;
- Tegra::MemoryManager& gpu_memory;
std::recursive_mutex mutex;
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index a04a76481..1cbfef090 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -16,6 +16,9 @@ class MemoryManager;
namespace Engines {
class AccelerateDMAInterface;
}
+namespace Control {
+struct ChannelState;
+}
} // namespace Tegra
namespace VideoCore {
@@ -37,7 +40,7 @@ public:
virtual ~RasterizerInterface() = default;
/// Dispatches a draw invocation
- virtual void Draw(bool is_indexed, bool is_instanced) = 0;
+ virtual void Draw(bool is_indexed, u32 instance_count) = 0;
/// Clear the current framebuffer
virtual void Clear() = 0;
@@ -59,7 +62,10 @@ public:
virtual void DisableGraphicsUniformBuffer(size_t stage, u32 index) = 0;
/// Signal a GPU based semaphore as a fence
- virtual void SignalSemaphore(GPUVAddr addr, u32 value) = 0;
+ virtual void SignalFence(std::function<void()>&& func) = 0;
+
+ /// Send an operation to be done after a certain amount of flushes.
+ virtual void SyncOperation(std::function<void()>&& func) = 0;
/// Signal a GPU based syncpoint as a fence
virtual void SignalSyncPoint(u32 value) = 0;
@@ -86,13 +92,13 @@ public:
virtual void OnCPUWrite(VAddr addr, u64 size) = 0;
/// Sync memory between guest and host.
- virtual void SyncGuestHost() = 0;
+ virtual void InvalidateGPUCache() = 0;
/// Unmap memory range
virtual void UnmapMemory(VAddr addr, u64 size) = 0;
/// Remap GPU memory range. This means underneath backing memory changed
- virtual void ModifyGPUMemory(GPUVAddr addr, u64 size) = 0;
+ virtual void ModifyGPUMemory(size_t as_id, GPUVAddr addr, u64 size) = 0;
/// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
/// and invalidated
@@ -123,7 +129,7 @@ public:
[[nodiscard]] virtual Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() = 0;
virtual void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
- std::span<u8> memory) = 0;
+ std::span<const u8> memory) = 0;
/// Attempt to use a faster method to display the framebuffer to screen
[[nodiscard]] virtual bool AccelerateDisplay(const Tegra::FramebufferConfig& config,
@@ -137,5 +143,11 @@ public:
/// Initialize disk cached resources for the game being emulated
virtual void LoadDiskResources(u64 title_id, std::stop_token stop_loading,
const DiskResourceLoadCallback& callback) {}
+
+ virtual void InitializeChannel(Tegra::Control::ChannelState& channel) {}
+
+ virtual void BindChannel(Tegra::Control::ChannelState& channel) {}
+
+ virtual void ReleaseChannel(s32 channel_id) {}
};
} // namespace VideoCore
diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp
index 45791aa75..e8761a747 100644
--- a/src/video_core/renderer_base.cpp
+++ b/src/video_core/renderer_base.cpp
@@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include <thread>
+
#include "common/logging/log.h"
#include "core/frontend/emu_window.h"
#include "video_core/renderer_base.h"
@@ -35,8 +37,12 @@ void RendererBase::RequestScreenshot(void* data, std::function<void(bool)> callb
LOG_ERROR(Render, "A screenshot is already requested or in progress, ignoring the request");
return;
}
+ auto async_callback{[callback = std::move(callback)](bool invert_y) {
+ std::thread t{callback, invert_y};
+ t.detach();
+ }};
renderer_settings.screenshot_bits = data;
- renderer_settings.screenshot_complete_callback = std::move(callback);
+ renderer_settings.screenshot_complete_callback = async_callback;
renderer_settings.screenshot_framebuffer_layout = layout;
renderer_settings.screenshot_requested = true;
}
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 32450ee1d..08f4d69ab 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -168,7 +168,7 @@ void BufferCacheRuntime::BindIndexBuffer(Buffer& buffer, u32 offset, u32 size) {
if (has_unified_vertex_buffers) {
buffer.MakeResident(GL_READ_ONLY);
glBufferAddressRangeNV(GL_ELEMENT_ARRAY_ADDRESS_NV, 0, buffer.HostGpuAddr() + offset,
- static_cast<GLsizeiptr>(size));
+ static_cast<GLsizeiptr>(Common::AlignUp(size, 4)));
} else {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.Handle());
index_buffer_offset = offset;
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
index 1f0f156ed..26d066004 100644
--- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
@@ -28,12 +28,11 @@ bool ComputePipelineKey::operator==(const ComputePipelineKey& rhs) const noexcep
}
ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cache_,
- BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
- Tegra::Engines::KeplerCompute& kepler_compute_,
- ProgramManager& program_manager_, const Shader::Info& info_,
- std::string code, std::vector<u32> code_v)
- : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_},
- kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_} {
+ BufferCache& buffer_cache_, ProgramManager& program_manager_,
+ const Shader::Info& info_, std::string code,
+ std::vector<u32> code_v)
+ : texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
+ program_manager{program_manager_}, info{info_} {
switch (device.GetShaderBackend()) {
case Settings::ShaderBackend::GLSL:
source_program = CreateProgram(code, GL_COMPUTE_SHADER);
@@ -86,7 +85,7 @@ void ComputePipeline::Configure() {
GLsizei texture_binding{};
GLsizei image_binding{};
- const auto& qmd{kepler_compute.launch_description};
+ const auto& qmd{kepler_compute->launch_description};
const auto& cbufs{qmd.const_buffer_config};
const bool via_header_index{qmd.linked_tsc != 0};
const auto read_handle{[&](const auto& desc, u32 index) {
@@ -101,12 +100,13 @@ void ComputePipeline::Configure() {
const u32 secondary_offset{desc.secondary_cbuf_offset + index_offset};
const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].Address() +
secondary_offset};
- const u32 lhs_raw{gpu_memory.Read<u32>(addr)};
- const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)};
+ const u32 lhs_raw{gpu_memory->Read<u32>(addr) << desc.shift_left};
+ const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)
+ << desc.secondary_shift_left};
return TexturePair(lhs_raw | rhs_raw, via_header_index);
}
}
- return TexturePair(gpu_memory.Read<u32>(addr), via_header_index);
+ return TexturePair(gpu_memory->Read<u32>(addr), via_header_index);
}};
const auto add_image{[&](const auto& desc, bool blacklist) {
for (u32 index = 0; index < desc.count; ++index) {
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.h b/src/video_core/renderer_opengl/gl_compute_pipeline.h
index 723f27f11..6534dec32 100644
--- a/src/video_core/renderer_opengl/gl_compute_pipeline.h
+++ b/src/video_core/renderer_opengl/gl_compute_pipeline.h
@@ -49,10 +49,8 @@ static_assert(std::is_trivially_constructible_v<ComputePipelineKey>);
class ComputePipeline {
public:
explicit ComputePipeline(const Device& device, TextureCache& texture_cache_,
- BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
- Tegra::Engines::KeplerCompute& kepler_compute_,
- ProgramManager& program_manager_, const Shader::Info& info_,
- std::string code, std::vector<u32> code_v);
+ BufferCache& buffer_cache_, ProgramManager& program_manager_,
+ const Shader::Info& info_, std::string code, std::vector<u32> code_v);
void Configure();
@@ -60,11 +58,17 @@ public:
return writes_global_memory;
}
+ void SetEngine(Tegra::Engines::KeplerCompute* kepler_compute_,
+ Tegra::MemoryManager* gpu_memory_) {
+ kepler_compute = kepler_compute_;
+ gpu_memory = gpu_memory_;
+ }
+
private:
TextureCache& texture_cache;
BufferCache& buffer_cache;
- Tegra::MemoryManager& gpu_memory;
- Tegra::Engines::KeplerCompute& kepler_compute;
+ Tegra::MemoryManager* gpu_memory;
+ Tegra::Engines::KeplerCompute* kepler_compute;
ProgramManager& program_manager;
Shader::Info info;
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.cpp b/src/video_core/renderer_opengl/gl_fence_manager.cpp
index 6e82c2e28..91463f854 100644
--- a/src/video_core/renderer_opengl/gl_fence_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_fence_manager.cpp
@@ -10,10 +10,7 @@
namespace OpenGL {
-GLInnerFence::GLInnerFence(u32 payload_, bool is_stubbed_) : FenceBase{payload_, is_stubbed_} {}
-
-GLInnerFence::GLInnerFence(GPUVAddr address_, u32 payload_, bool is_stubbed_)
- : FenceBase{address_, payload_, is_stubbed_} {}
+GLInnerFence::GLInnerFence(bool is_stubbed_) : FenceBase{is_stubbed_} {}
GLInnerFence::~GLInnerFence() = default;
@@ -48,12 +45,8 @@ FenceManagerOpenGL::FenceManagerOpenGL(VideoCore::RasterizerInterface& rasterize
BufferCache& buffer_cache_, QueryCache& query_cache_)
: GenericFenceManager{rasterizer_, gpu_, texture_cache_, buffer_cache_, query_cache_} {}
-Fence FenceManagerOpenGL::CreateFence(u32 value, bool is_stubbed) {
- return std::make_shared<GLInnerFence>(value, is_stubbed);
-}
-
-Fence FenceManagerOpenGL::CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) {
- return std::make_shared<GLInnerFence>(addr, value, is_stubbed);
+Fence FenceManagerOpenGL::CreateFence(bool is_stubbed) {
+ return std::make_shared<GLInnerFence>(is_stubbed);
}
void FenceManagerOpenGL::QueueFence(Fence& fence) {
diff --git a/src/video_core/renderer_opengl/gl_fence_manager.h b/src/video_core/renderer_opengl/gl_fence_manager.h
index 14ff00db2..f1446e732 100644
--- a/src/video_core/renderer_opengl/gl_fence_manager.h
+++ b/src/video_core/renderer_opengl/gl_fence_manager.h
@@ -16,8 +16,7 @@ namespace OpenGL {
class GLInnerFence : public VideoCommon::FenceBase {
public:
- explicit GLInnerFence(u32 payload_, bool is_stubbed_);
- explicit GLInnerFence(GPUVAddr address_, u32 payload_, bool is_stubbed_);
+ explicit GLInnerFence(bool is_stubbed_);
~GLInnerFence();
void Queue();
@@ -40,8 +39,7 @@ public:
QueryCache& query_cache);
protected:
- Fence CreateFence(u32 value, bool is_stubbed) override;
- Fence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) override;
+ Fence CreateFence(bool is_stubbed) override;
void QueueFence(Fence& fence) override;
bool IsFenceSignaled(Fence& fence) const override;
void WaitFence(Fence& fence) override;
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index c297f7121..daceb05f4 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -73,8 +73,8 @@ GLenum AssemblyStage(size_t stage_index) {
/// @param location Hardware location
/// @return Pair of ARB_transform_feedback3 token stream first and third arguments
/// @note Read https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_transform_feedback3.txt
-std::pair<GLint, GLint> TransformFeedbackEnum(u8 location) {
- const u8 index = location / 4;
+std::pair<GLint, GLint> TransformFeedbackEnum(u32 location) {
+ const auto index = location / 4;
if (index >= 8 && index <= 39) {
return {GL_GENERIC_ATTRIB_NV, index - 8};
}
@@ -169,15 +169,15 @@ ConfigureFuncPtr ConfigureFunc(const std::array<Shader::Info, 5>& infos, u32 ena
}
} // Anonymous namespace
-GraphicsPipeline::GraphicsPipeline(
- const Device& device, TextureCache& texture_cache_, BufferCache& buffer_cache_,
- Tegra::MemoryManager& gpu_memory_, Tegra::Engines::Maxwell3D& maxwell3d_,
- ProgramManager& program_manager_, StateTracker& state_tracker_, ShaderWorker* thread_worker,
- VideoCore::ShaderNotify* shader_notify, std::array<std::string, 5> sources,
- std::array<std::vector<u32>, 5> sources_spirv, const std::array<const Shader::Info*, 5>& infos,
- const GraphicsPipelineKey& key_)
- : texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
- gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, program_manager{program_manager_},
+GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_cache_,
+ BufferCache& buffer_cache_, ProgramManager& program_manager_,
+ StateTracker& state_tracker_, ShaderWorker* thread_worker,
+ VideoCore::ShaderNotify* shader_notify,
+ std::array<std::string, 5> sources,
+ std::array<std::vector<u32>, 5> sources_spirv,
+ const std::array<const Shader::Info*, 5>& infos,
+ const GraphicsPipelineKey& key_)
+ : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, program_manager{program_manager_},
state_tracker{state_tracker_}, key{key_} {
if (shader_notify) {
shader_notify->MarkShaderBuilding();
@@ -285,8 +285,8 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
buffer_cache.runtime.SetBaseStorageBindings(base_storage_bindings);
buffer_cache.runtime.SetEnableStorageBuffers(use_storage_buffers);
- const auto& regs{maxwell3d.regs};
- const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex};
+ const auto& regs{maxwell3d->regs};
+ const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding};
const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE {
const Shader::Info& info{stage_infos[stage]};
buffer_cache.UnbindGraphicsStorageBuffers(stage);
@@ -299,7 +299,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
++ssbo_index;
}
}
- const auto& cbufs{maxwell3d.state.shader_stages[stage].const_buffers};
+ const auto& cbufs{maxwell3d->state.shader_stages[stage].const_buffers};
const auto read_handle{[&](const auto& desc, u32 index) {
ASSERT(cbufs[desc.cbuf_index].enabled);
const u32 index_offset{index << desc.size_shift};
@@ -312,13 +312,14 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
const u32 second_offset{desc.secondary_cbuf_offset + index_offset};
const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address +
second_offset};
- const u32 lhs_raw{gpu_memory.Read<u32>(addr)};
- const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)};
+ const u32 lhs_raw{gpu_memory->Read<u32>(addr) << desc.shift_left};
+ const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)
+ << desc.secondary_shift_left};
const u32 raw{lhs_raw | rhs_raw};
return TexturePair(raw, via_header_index);
}
}
- return TexturePair(gpu_memory.Read<u32>(addr), via_header_index);
+ return TexturePair(gpu_memory->Read<u32>(addr), via_header_index);
}};
const auto add_image{[&](const auto& desc, bool blacklist) LAMBDA_FORCEINLINE {
for (u32 index = 0; index < desc.count; ++index) {
@@ -567,10 +568,25 @@ void GraphicsPipeline::GenerateTransformFeedbackState() {
++current_stream;
const auto& locations = key.xfb_state.varyings[feedback];
- std::optional<u8> current_index;
+ std::optional<u32> current_index;
for (u32 offset = 0; offset < layout.varying_count; ++offset) {
- const u8 location = locations[offset];
- const u8 index = location / 4;
+ const auto get_attribute = [&locations](u32 index) -> u32 {
+ switch (index % 4) {
+ case 0:
+ return locations[index / 4].attribute0.Value();
+ case 1:
+ return locations[index / 4].attribute1.Value();
+ case 2:
+ return locations[index / 4].attribute2.Value();
+ case 3:
+ return locations[index / 4].attribute3.Value();
+ }
+ UNREACHABLE();
+ return 0;
+ };
+
+ const auto attribute{get_attribute(offset)};
+ const auto index = attribute / 4U;
if (current_index == index) {
// Increase number of components of the previous attachment
@@ -579,7 +595,7 @@ void GraphicsPipeline::GenerateTransformFeedbackState() {
}
current_index = index;
- std::tie(cursor[0], cursor[2]) = TransformFeedbackEnum(location);
+ std::tie(cursor[0], cursor[2]) = TransformFeedbackEnum(attribute);
cursor[1] = 1;
cursor += XFB_ENTRY_STRIDE;
}
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
index 4ec15b966..ea53ddb46 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
@@ -37,8 +37,8 @@ struct GraphicsPipelineKey {
BitField<0, 1, u32> xfb_enabled;
BitField<1, 1, u32> early_z;
BitField<2, 4, Maxwell::PrimitiveTopology> gs_input_topology;
- BitField<6, 2, Maxwell::TessellationPrimitive> tessellation_primitive;
- BitField<8, 2, Maxwell::TessellationSpacing> tessellation_spacing;
+ BitField<6, 2, Maxwell::Tessellation::DomainType> tessellation_primitive;
+ BitField<8, 2, Maxwell::Tessellation::Spacing> tessellation_spacing;
BitField<10, 1, u32> tessellation_clockwise;
};
std::array<u32, 3> padding;
@@ -71,10 +71,9 @@ static_assert(std::is_trivially_constructible_v<GraphicsPipelineKey>);
class GraphicsPipeline {
public:
explicit GraphicsPipeline(const Device& device, TextureCache& texture_cache_,
- BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
- Tegra::Engines::Maxwell3D& maxwell3d_,
- ProgramManager& program_manager_, StateTracker& state_tracker_,
- ShaderWorker* thread_worker, VideoCore::ShaderNotify* shader_notify,
+ BufferCache& buffer_cache_, ProgramManager& program_manager_,
+ StateTracker& state_tracker_, ShaderWorker* thread_worker,
+ VideoCore::ShaderNotify* shader_notify,
std::array<std::string, 5> sources,
std::array<std::vector<u32>, 5> sources_spirv,
const std::array<const Shader::Info*, 5>& infos,
@@ -107,6 +106,11 @@ public:
};
}
+ void SetEngine(Tegra::Engines::Maxwell3D* maxwell3d_, Tegra::MemoryManager* gpu_memory_) {
+ maxwell3d = maxwell3d_;
+ gpu_memory = gpu_memory_;
+ }
+
private:
template <typename Spec>
void ConfigureImpl(bool is_indexed);
@@ -119,8 +123,8 @@ private:
TextureCache& texture_cache;
BufferCache& buffer_cache;
- Tegra::MemoryManager& gpu_memory;
- Tegra::Engines::Maxwell3D& maxwell3d;
+ Tegra::MemoryManager* gpu_memory;
+ Tegra::Engines::Maxwell3D* maxwell3d;
ProgramManager& program_manager;
StateTracker& state_tracker;
const GraphicsPipelineKey key;
diff --git a/src/video_core/renderer_opengl/gl_query_cache.cpp b/src/video_core/renderer_opengl/gl_query_cache.cpp
index ed40f5791..5070db441 100644
--- a/src/video_core/renderer_opengl/gl_query_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_query_cache.cpp
@@ -26,9 +26,8 @@ constexpr GLenum GetTarget(VideoCore::QueryType type) {
} // Anonymous namespace
-QueryCache::QueryCache(RasterizerOpenGL& rasterizer_, Tegra::Engines::Maxwell3D& maxwell3d_,
- Tegra::MemoryManager& gpu_memory_)
- : QueryCacheBase(rasterizer_, maxwell3d_, gpu_memory_), gl_rasterizer{rasterizer_} {}
+QueryCache::QueryCache(RasterizerOpenGL& rasterizer_)
+ : QueryCacheBase(rasterizer_), gl_rasterizer{rasterizer_} {}
QueryCache::~QueryCache() = default;
diff --git a/src/video_core/renderer_opengl/gl_query_cache.h b/src/video_core/renderer_opengl/gl_query_cache.h
index 8a49f1ef0..14ce59990 100644
--- a/src/video_core/renderer_opengl/gl_query_cache.h
+++ b/src/video_core/renderer_opengl/gl_query_cache.h
@@ -28,8 +28,7 @@ using CounterStream = VideoCommon::CounterStreamBase<QueryCache, HostCounter>;
class QueryCache final
: public VideoCommon::QueryCacheBase<QueryCache, CachedQuery, CounterStream, HostCounter> {
public:
- explicit QueryCache(RasterizerOpenGL& rasterizer_, Tegra::Engines::Maxwell3D& maxwell3d_,
- Tegra::MemoryManager& gpu_memory_);
+ explicit QueryCache(RasterizerOpenGL& rasterizer_);
~QueryCache();
OGLQuery AllocateQuery(VideoCore::QueryType type);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index f018333af..79d7908d4 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -16,7 +16,7 @@
#include "common/microprofile.h"
#include "common/scope_exit.h"
#include "common/settings.h"
-
+#include "video_core/control/channel_state.h"
#include "video_core/engines/kepler_compute.h"
#include "video_core/engines/maxwell_3d.h"
#include "video_core/memory_manager.h"
@@ -56,22 +56,20 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra
Core::Memory::Memory& cpu_memory_, const Device& device_,
ScreenInfo& screen_info_, ProgramManager& program_manager_,
StateTracker& state_tracker_)
- : RasterizerAccelerated(cpu_memory_), gpu(gpu_), maxwell3d(gpu.Maxwell3D()),
- kepler_compute(gpu.KeplerCompute()), gpu_memory(gpu.MemoryManager()), device(device_),
- screen_info(screen_info_), program_manager(program_manager_), state_tracker(state_tracker_),
+ : RasterizerAccelerated(cpu_memory_), gpu(gpu_), device(device_), screen_info(screen_info_),
+ program_manager(program_manager_), state_tracker(state_tracker_),
texture_cache_runtime(device, program_manager, state_tracker),
- texture_cache(texture_cache_runtime, *this, maxwell3d, kepler_compute, gpu_memory),
- buffer_cache_runtime(device),
- buffer_cache(*this, maxwell3d, kepler_compute, gpu_memory, cpu_memory_, buffer_cache_runtime),
- shader_cache(*this, emu_window_, maxwell3d, kepler_compute, gpu_memory, device, texture_cache,
- buffer_cache, program_manager, state_tracker, gpu.ShaderNotify()),
- query_cache(*this, maxwell3d, gpu_memory), accelerate_dma(buffer_cache),
+ texture_cache(texture_cache_runtime, *this), buffer_cache_runtime(device),
+ buffer_cache(*this, cpu_memory_, buffer_cache_runtime),
+ shader_cache(*this, emu_window_, device, texture_cache, buffer_cache, program_manager,
+ state_tracker, gpu.ShaderNotify()),
+ query_cache(*this), accelerate_dma(buffer_cache),
fence_manager(*this, gpu, texture_cache, buffer_cache, query_cache) {}
RasterizerOpenGL::~RasterizerOpenGL() = default;
void RasterizerOpenGL::SyncVertexFormats() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::VertexFormats]) {
return;
}
@@ -89,7 +87,7 @@ void RasterizerOpenGL::SyncVertexFormats() {
}
flags[Dirty::VertexFormat0 + index] = false;
- const auto attrib = maxwell3d.regs.vertex_attrib_format[index];
+ const auto& attrib = maxwell3d->regs.vertex_attrib_format[index];
const auto gl_index = static_cast<GLuint>(index);
// Disable constant attributes.
@@ -99,8 +97,8 @@ void RasterizerOpenGL::SyncVertexFormats() {
}
glEnableVertexAttribArray(gl_index);
- if (attrib.type == Maxwell::VertexAttribute::Type::SignedInt ||
- attrib.type == Maxwell::VertexAttribute::Type::UnsignedInt) {
+ if (attrib.type == Maxwell::VertexAttribute::Type::SInt ||
+ attrib.type == Maxwell::VertexAttribute::Type::UInt) {
glVertexAttribIFormat(gl_index, attrib.ComponentCount(),
MaxwellToGL::VertexFormat(attrib), attrib.offset);
} else {
@@ -113,13 +111,13 @@ void RasterizerOpenGL::SyncVertexFormats() {
}
void RasterizerOpenGL::SyncVertexInstances() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::VertexInstances]) {
return;
}
flags[Dirty::VertexInstances] = false;
- const auto& regs = maxwell3d.regs;
+ const auto& regs = maxwell3d->regs;
for (std::size_t index = 0; index < NUM_SUPPORTED_VERTEX_ATTRIBUTES; ++index) {
if (!flags[Dirty::VertexInstance0 + index]) {
continue;
@@ -127,8 +125,8 @@ void RasterizerOpenGL::SyncVertexInstances() {
flags[Dirty::VertexInstance0 + index] = false;
const auto gl_index = static_cast<GLuint>(index);
- const bool instancing_enabled = regs.instanced_arrays.IsInstancingEnabled(gl_index);
- const GLuint divisor = instancing_enabled ? regs.vertex_array[index].divisor : 0;
+ const bool instancing_enabled = regs.vertex_stream_instances.IsInstancingEnabled(gl_index);
+ const GLuint divisor = instancing_enabled ? regs.vertex_streams[index].frequency : 0;
glVertexBindingDivisor(gl_index, divisor);
}
}
@@ -140,36 +138,36 @@ void RasterizerOpenGL::LoadDiskResources(u64 title_id, std::stop_token stop_load
void RasterizerOpenGL::Clear() {
MICROPROFILE_SCOPE(OpenGL_Clears);
- if (!maxwell3d.ShouldExecute()) {
+ if (!maxwell3d->ShouldExecute()) {
return;
}
- const auto& regs = maxwell3d.regs;
+ const auto& regs = maxwell3d->regs;
bool use_color{};
bool use_depth{};
bool use_stencil{};
- if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
- regs.clear_buffers.A) {
+ if (regs.clear_surface.R || regs.clear_surface.G || regs.clear_surface.B ||
+ regs.clear_surface.A) {
use_color = true;
- const GLuint index = regs.clear_buffers.RT;
+ const GLuint index = regs.clear_surface.RT;
state_tracker.NotifyColorMask(index);
- glColorMaski(index, regs.clear_buffers.R != 0, regs.clear_buffers.G != 0,
- regs.clear_buffers.B != 0, regs.clear_buffers.A != 0);
+ glColorMaski(index, regs.clear_surface.R != 0, regs.clear_surface.G != 0,
+ regs.clear_surface.B != 0, regs.clear_surface.A != 0);
// TODO(Rodrigo): Determine if clamping is used on clears
SyncFragmentColorClampState();
SyncFramebufferSRGB();
}
- if (regs.clear_buffers.Z) {
+ if (regs.clear_surface.Z) {
ASSERT_MSG(regs.zeta_enable != 0, "Tried to clear Z but buffer is not enabled!");
use_depth = true;
state_tracker.NotifyDepthMask();
glDepthMask(GL_TRUE);
}
- if (regs.clear_buffers.S) {
+ if (regs.clear_surface.S) {
ASSERT_MSG(regs.zeta_enable, "Tried to clear stencil but buffer is not enabled!");
use_stencil = true;
}
@@ -186,16 +184,16 @@ void RasterizerOpenGL::Clear() {
texture_cache.UpdateRenderTargets(true);
state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle());
SyncViewport();
- if (regs.clear_flags.scissor) {
+ if (regs.clear_control.use_scissor) {
SyncScissorTest();
} else {
state_tracker.NotifyScissor0();
glDisablei(GL_SCISSOR_TEST, 0);
}
- UNIMPLEMENTED_IF(regs.clear_flags.viewport);
+ UNIMPLEMENTED_IF(regs.clear_control.use_viewport_clip0);
if (use_color) {
- glClearBufferfv(GL_COLOR, regs.clear_buffers.RT, regs.clear_color);
+ glClearBufferfv(GL_COLOR, regs.clear_surface.RT, regs.clear_color.data());
}
if (use_depth && use_stencil) {
glClearBufferfi(GL_DEPTH_STENCIL, 0, regs.clear_depth, regs.clear_stencil);
@@ -207,7 +205,7 @@ void RasterizerOpenGL::Clear() {
++num_queued_commands;
}
-void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
+void RasterizerOpenGL::Draw(bool is_indexed, u32 instance_count) {
MICROPROFILE_SCOPE(OpenGL_Drawing);
SCOPE_EXIT({ gpu.TickWork(); });
@@ -217,22 +215,27 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
if (!pipeline) {
return;
}
+
+ gpu.TickWork();
+
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ pipeline->SetEngine(maxwell3d, gpu_memory);
pipeline->Configure(is_indexed);
+ BindInlineIndexBuffer();
+
SyncState();
- const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d.regs.draw.topology);
+ const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d->regs.draw.topology);
BeginTransformFeedback(pipeline, primitive_mode);
- const GLuint base_instance = static_cast<GLuint>(maxwell3d.regs.vb_base_instance);
- const GLsizei num_instances =
- static_cast<GLsizei>(is_instanced ? maxwell3d.mme_draw.instance_count : 1);
+ const GLuint base_instance = static_cast<GLuint>(maxwell3d->regs.global_base_instance_index);
+ const GLsizei num_instances = static_cast<GLsizei>(instance_count);
if (is_indexed) {
- const GLint base_vertex = static_cast<GLint>(maxwell3d.regs.vb_element_base);
- const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d.regs.index_array.count);
+ const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.global_base_vertex_index);
+ const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.index_buffer.count);
const GLvoid* const offset = buffer_cache_runtime.IndexOffset();
- const GLenum format = MaxwellToGL::IndexFormat(maxwell3d.regs.index_array.format);
+ const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format);
if (num_instances == 1 && base_instance == 0 && base_vertex == 0) {
glDrawElements(primitive_mode, num_vertices, format, offset);
} else if (num_instances == 1 && base_instance == 0) {
@@ -251,8 +254,8 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
base_instance);
}
} else {
- const GLint base_vertex = static_cast<GLint>(maxwell3d.regs.vertex_buffer.first);
- const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d.regs.vertex_buffer.count);
+ const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.vertex_buffer.first);
+ const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.vertex_buffer.count);
if (num_instances == 1 && base_instance == 0) {
glDrawArrays(primitive_mode, base_vertex, num_vertices);
} else if (base_instance == 0) {
@@ -273,8 +276,9 @@ void RasterizerOpenGL::DispatchCompute() {
if (!pipeline) {
return;
}
+ pipeline->SetEngine(kepler_compute, gpu_memory);
pipeline->Configure();
- const auto& qmd{kepler_compute.launch_description};
+ const auto& qmd{kepler_compute->launch_description};
glDispatchCompute(qmd.grid_dim_x, qmd.grid_dim_y, qmd.grid_dim_z);
++num_queued_commands;
has_written_global_memory |= pipeline->WritesGlobalMemory();
@@ -359,7 +363,7 @@ void RasterizerOpenGL::OnCPUWrite(VAddr addr, u64 size) {
}
}
-void RasterizerOpenGL::SyncGuestHost() {
+void RasterizerOpenGL::InvalidateGPUCache() {
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
shader_cache.SyncGuestHost();
{
@@ -380,40 +384,30 @@ void RasterizerOpenGL::UnmapMemory(VAddr addr, u64 size) {
shader_cache.OnCPUWrite(addr, size);
}
-void RasterizerOpenGL::ModifyGPUMemory(GPUVAddr addr, u64 size) {
+void RasterizerOpenGL::ModifyGPUMemory(size_t as_id, GPUVAddr addr, u64 size) {
{
std::scoped_lock lock{texture_cache.mutex};
- texture_cache.UnmapGPUMemory(addr, size);
+ texture_cache.UnmapGPUMemory(as_id, addr, size);
}
}
-void RasterizerOpenGL::SignalSemaphore(GPUVAddr addr, u32 value) {
- if (!gpu.IsAsync()) {
- gpu_memory.Write<u32>(addr, value);
- return;
- }
- fence_manager.SignalSemaphore(addr, value);
+void RasterizerOpenGL::SignalFence(std::function<void()>&& func) {
+ fence_manager.SignalFence(std::move(func));
+}
+
+void RasterizerOpenGL::SyncOperation(std::function<void()>&& func) {
+ fence_manager.SyncOperation(std::move(func));
}
void RasterizerOpenGL::SignalSyncPoint(u32 value) {
- if (!gpu.IsAsync()) {
- gpu.IncrementSyncPoint(value);
- return;
- }
fence_manager.SignalSyncPoint(value);
}
void RasterizerOpenGL::SignalReference() {
- if (!gpu.IsAsync()) {
- return;
- }
fence_manager.SignalOrdering();
}
void RasterizerOpenGL::ReleaseFences() {
- if (!gpu.IsAsync()) {
- return;
- }
fence_manager.WaitPendingFences();
}
@@ -430,6 +424,7 @@ void RasterizerOpenGL::WaitForIdle() {
}
void RasterizerOpenGL::FragmentBarrier() {
+ glTextureBarrier();
glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT | GL_TEXTURE_FETCH_BARRIER_BIT);
}
@@ -482,13 +477,13 @@ Tegra::Engines::AccelerateDMAInterface& RasterizerOpenGL::AccessAccelerateDMA()
}
void RasterizerOpenGL::AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
- std::span<u8> memory) {
- auto cpu_addr = gpu_memory.GpuToCpuAddress(address);
+ std::span<const u8> memory) {
+ auto cpu_addr = gpu_memory->GpuToCpuAddress(address);
if (!cpu_addr) [[unlikely]] {
- gpu_memory.WriteBlock(address, memory.data(), copy_size);
+ gpu_memory->WriteBlock(address, memory.data(), copy_size);
return;
}
- gpu_memory.WriteBlockUnsafe(address, memory.data(), copy_size);
+ gpu_memory->WriteBlockUnsafe(address, memory.data(), copy_size);
{
std::unique_lock<std::mutex> lock{buffer_cache.mutex};
if (!buffer_cache.InlineMemory(*cpu_addr, copy_size, memory)) {
@@ -551,8 +546,8 @@ void RasterizerOpenGL::SyncState() {
}
void RasterizerOpenGL::SyncViewport() {
- auto& flags = maxwell3d.dirty.flags;
- const auto& regs = maxwell3d.regs;
+ auto& flags = maxwell3d->dirty.flags;
+ const auto& regs = maxwell3d->regs;
const bool rescale_viewports = flags[VideoCommon::Dirty::RescaleViewports];
const bool dirty_viewport = flags[Dirty::Viewports] || rescale_viewports;
@@ -561,9 +556,9 @@ void RasterizerOpenGL::SyncViewport() {
if (dirty_viewport || dirty_clip_control || flags[Dirty::FrontFace]) {
flags[Dirty::FrontFace] = false;
- GLenum mode = MaxwellToGL::FrontFace(regs.front_face);
+ GLenum mode = MaxwellToGL::FrontFace(regs.gl_front_face);
bool flip_faces = true;
- if (regs.screen_y_control.triangle_rast_flip != 0) {
+ if (regs.window_origin.flip_y != 0) {
flip_faces = !flip_faces;
}
if (regs.viewport_transform[0].scale_y < 0.0f) {
@@ -588,14 +583,15 @@ void RasterizerOpenGL::SyncViewport() {
if (regs.viewport_transform[0].scale_y < 0.0f) {
flip_y = !flip_y;
}
- if (regs.screen_y_control.y_negate != 0) {
+ const bool lower_left{regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft};
+ if (lower_left) {
flip_y = !flip_y;
}
const bool is_zero_to_one = regs.depth_mode == Maxwell::DepthMode::ZeroToOne;
const GLenum origin = flip_y ? GL_UPPER_LEFT : GL_LOWER_LEFT;
const GLenum depth = is_zero_to_one ? GL_ZERO_TO_ONE : GL_NEGATIVE_ONE_TO_ONE;
state_tracker.ClipControl(origin, depth);
- state_tracker.SetYNegate(regs.screen_y_control.y_negate != 0);
+ state_tracker.SetYNegate(lower_left);
}
const bool is_rescaling{texture_cache.IsRescaling()};
const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f;
@@ -667,23 +663,29 @@ void RasterizerOpenGL::SyncViewport() {
}
void RasterizerOpenGL::SyncDepthClamp() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::DepthClampEnabled]) {
return;
}
flags[Dirty::DepthClampEnabled] = false;
- oglEnable(GL_DEPTH_CLAMP, maxwell3d.regs.view_volume_clip_control.depth_clamp_disabled == 0);
+ bool depth_clamp_disabled{maxwell3d->regs.viewport_clip_control.geometry_clip ==
+ Maxwell::ViewportClipControl::GeometryClip::Passthrough ||
+ maxwell3d->regs.viewport_clip_control.geometry_clip ==
+ Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ ||
+ maxwell3d->regs.viewport_clip_control.geometry_clip ==
+ Maxwell::ViewportClipControl::GeometryClip::FrustumZ};
+ oglEnable(GL_DEPTH_CLAMP, !depth_clamp_disabled);
}
void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::ClipDistances] && !flags[VideoCommon::Dirty::Shaders]) {
return;
}
flags[Dirty::ClipDistances] = false;
- clip_mask &= maxwell3d.regs.clip_distance_enabled;
+ clip_mask &= maxwell3d->regs.user_clip_enable.raw;
if (clip_mask == last_clip_distance_mask) {
return;
}
@@ -699,15 +701,15 @@ void RasterizerOpenGL::SyncClipCoef() {
}
void RasterizerOpenGL::SyncCullMode() {
- auto& flags = maxwell3d.dirty.flags;
- const auto& regs = maxwell3d.regs;
+ auto& flags = maxwell3d->dirty.flags;
+ const auto& regs = maxwell3d->regs;
if (flags[Dirty::CullTest]) {
flags[Dirty::CullTest] = false;
- if (regs.cull_test_enabled) {
+ if (regs.gl_cull_test_enabled) {
glEnable(GL_CULL_FACE);
- glCullFace(MaxwellToGL::CullFace(regs.cull_face));
+ glCullFace(MaxwellToGL::CullFace(regs.gl_cull_face));
} else {
glDisable(GL_CULL_FACE);
}
@@ -715,23 +717,23 @@ void RasterizerOpenGL::SyncCullMode() {
}
void RasterizerOpenGL::SyncPrimitiveRestart() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::PrimitiveRestart]) {
return;
}
flags[Dirty::PrimitiveRestart] = false;
- if (maxwell3d.regs.primitive_restart.enabled) {
+ if (maxwell3d->regs.primitive_restart.enabled) {
glEnable(GL_PRIMITIVE_RESTART);
- glPrimitiveRestartIndex(maxwell3d.regs.primitive_restart.index);
+ glPrimitiveRestartIndex(maxwell3d->regs.primitive_restart.index);
} else {
glDisable(GL_PRIMITIVE_RESTART);
}
}
void RasterizerOpenGL::SyncDepthTestState() {
- auto& flags = maxwell3d.dirty.flags;
- const auto& regs = maxwell3d.regs;
+ auto& flags = maxwell3d->dirty.flags;
+ const auto& regs = maxwell3d->regs;
if (flags[Dirty::DepthMask]) {
flags[Dirty::DepthMask] = false;
@@ -750,28 +752,28 @@ void RasterizerOpenGL::SyncDepthTestState() {
}
void RasterizerOpenGL::SyncStencilTestState() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::StencilTest]) {
return;
}
flags[Dirty::StencilTest] = false;
- const auto& regs = maxwell3d.regs;
+ const auto& regs = maxwell3d->regs;
oglEnable(GL_STENCIL_TEST, regs.stencil_enable);
- glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_func_func),
- regs.stencil_front_func_ref, regs.stencil_front_func_mask);
- glStencilOpSeparate(GL_FRONT, MaxwellToGL::StencilOp(regs.stencil_front_op_fail),
- MaxwellToGL::StencilOp(regs.stencil_front_op_zfail),
- MaxwellToGL::StencilOp(regs.stencil_front_op_zpass));
+ glStencilFuncSeparate(GL_FRONT, MaxwellToGL::ComparisonOp(regs.stencil_front_op.func),
+ regs.stencil_front_ref, regs.stencil_front_func_mask);
+ glStencilOpSeparate(GL_FRONT, MaxwellToGL::StencilOp(regs.stencil_front_op.fail),
+ MaxwellToGL::StencilOp(regs.stencil_front_op.zfail),
+ MaxwellToGL::StencilOp(regs.stencil_front_op.zpass));
glStencilMaskSeparate(GL_FRONT, regs.stencil_front_mask);
if (regs.stencil_two_side_enable) {
- glStencilFuncSeparate(GL_BACK, MaxwellToGL::ComparisonOp(regs.stencil_back_func_func),
- regs.stencil_back_func_ref, regs.stencil_back_func_mask);
- glStencilOpSeparate(GL_BACK, MaxwellToGL::StencilOp(regs.stencil_back_op_fail),
- MaxwellToGL::StencilOp(regs.stencil_back_op_zfail),
- MaxwellToGL::StencilOp(regs.stencil_back_op_zpass));
+ glStencilFuncSeparate(GL_BACK, MaxwellToGL::ComparisonOp(regs.stencil_back_op.func),
+ regs.stencil_back_ref, regs.stencil_back_mask);
+ glStencilOpSeparate(GL_BACK, MaxwellToGL::StencilOp(regs.stencil_back_op.fail),
+ MaxwellToGL::StencilOp(regs.stencil_back_op.zfail),
+ MaxwellToGL::StencilOp(regs.stencil_back_op.zpass));
glStencilMaskSeparate(GL_BACK, regs.stencil_back_mask);
} else {
glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, 0xFFFFFFFF);
@@ -781,24 +783,24 @@ void RasterizerOpenGL::SyncStencilTestState() {
}
void RasterizerOpenGL::SyncRasterizeEnable() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::RasterizeEnable]) {
return;
}
flags[Dirty::RasterizeEnable] = false;
- oglEnable(GL_RASTERIZER_DISCARD, maxwell3d.regs.rasterize_enable == 0);
+ oglEnable(GL_RASTERIZER_DISCARD, maxwell3d->regs.rasterize_enable == 0);
}
void RasterizerOpenGL::SyncPolygonModes() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::PolygonModes]) {
return;
}
flags[Dirty::PolygonModes] = false;
- const auto& regs = maxwell3d.regs;
- if (regs.fill_rectangle) {
+ const auto& regs = maxwell3d->regs;
+ if (regs.fill_via_triangle_mode != Maxwell::FillViaTriangleMode::Disabled) {
if (!GLAD_GL_NV_fill_rectangle) {
LOG_ERROR(Render_OpenGL, "GL_NV_fill_rectangle used and not supported");
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@@ -830,7 +832,7 @@ void RasterizerOpenGL::SyncPolygonModes() {
}
void RasterizerOpenGL::SyncColorMask() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::ColorMasks]) {
return;
}
@@ -839,7 +841,7 @@ void RasterizerOpenGL::SyncColorMask() {
const bool force = flags[Dirty::ColorMaskCommon];
flags[Dirty::ColorMaskCommon] = false;
- const auto& regs = maxwell3d.regs;
+ const auto& regs = maxwell3d->regs;
if (regs.color_mask_common) {
if (!force && !flags[Dirty::ColorMask0]) {
return;
@@ -864,30 +866,31 @@ void RasterizerOpenGL::SyncColorMask() {
}
void RasterizerOpenGL::SyncMultiSampleState() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::MultisampleControl]) {
return;
}
flags[Dirty::MultisampleControl] = false;
- const auto& regs = maxwell3d.regs;
- oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.multisample_control.alpha_to_coverage);
- oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.multisample_control.alpha_to_one);
+ const auto& regs = maxwell3d->regs;
+ oglEnable(GL_SAMPLE_ALPHA_TO_COVERAGE, regs.anti_alias_alpha_control.alpha_to_coverage);
+ oglEnable(GL_SAMPLE_ALPHA_TO_ONE, regs.anti_alias_alpha_control.alpha_to_one);
}
void RasterizerOpenGL::SyncFragmentColorClampState() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::FragmentClampColor]) {
return;
}
flags[Dirty::FragmentClampColor] = false;
- glClampColor(GL_CLAMP_FRAGMENT_COLOR, maxwell3d.regs.frag_color_clamp ? GL_TRUE : GL_FALSE);
+ glClampColor(GL_CLAMP_FRAGMENT_COLOR,
+ maxwell3d->regs.frag_color_clamp.AnyEnabled() ? GL_TRUE : GL_FALSE);
}
void RasterizerOpenGL::SyncBlendState() {
- auto& flags = maxwell3d.dirty.flags;
- const auto& regs = maxwell3d.regs;
+ auto& flags = maxwell3d->dirty.flags;
+ const auto& regs = maxwell3d->regs;
if (flags[Dirty::BlendColor]) {
flags[Dirty::BlendColor] = false;
@@ -902,18 +905,18 @@ void RasterizerOpenGL::SyncBlendState() {
}
flags[Dirty::BlendStates] = false;
- if (!regs.independent_blend_enable) {
+ if (!regs.blend_per_target_enabled) {
if (!regs.blend.enable[0]) {
glDisable(GL_BLEND);
return;
}
glEnable(GL_BLEND);
- glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb),
- MaxwellToGL::BlendFunc(regs.blend.factor_dest_rgb),
- MaxwellToGL::BlendFunc(regs.blend.factor_source_a),
- MaxwellToGL::BlendFunc(regs.blend.factor_dest_a));
- glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.equation_rgb),
- MaxwellToGL::BlendEquation(regs.blend.equation_a));
+ glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.color_source),
+ MaxwellToGL::BlendFunc(regs.blend.color_dest),
+ MaxwellToGL::BlendFunc(regs.blend.alpha_source),
+ MaxwellToGL::BlendFunc(regs.blend.alpha_dest));
+ glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.color_op),
+ MaxwellToGL::BlendEquation(regs.blend.alpha_op));
return;
}
@@ -932,35 +935,34 @@ void RasterizerOpenGL::SyncBlendState() {
}
glEnablei(GL_BLEND, static_cast<GLuint>(i));
- const auto& src = regs.independent_blend[i];
- glBlendFuncSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendFunc(src.factor_source_rgb),
- MaxwellToGL::BlendFunc(src.factor_dest_rgb),
- MaxwellToGL::BlendFunc(src.factor_source_a),
- MaxwellToGL::BlendFunc(src.factor_dest_a));
- glBlendEquationSeparatei(static_cast<GLuint>(i),
- MaxwellToGL::BlendEquation(src.equation_rgb),
- MaxwellToGL::BlendEquation(src.equation_a));
+ const auto& src = regs.blend_per_target[i];
+ glBlendFuncSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendFunc(src.color_source),
+ MaxwellToGL::BlendFunc(src.color_dest),
+ MaxwellToGL::BlendFunc(src.alpha_source),
+ MaxwellToGL::BlendFunc(src.alpha_dest));
+ glBlendEquationSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendEquation(src.color_op),
+ MaxwellToGL::BlendEquation(src.alpha_op));
}
}
void RasterizerOpenGL::SyncLogicOpState() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::LogicOp]) {
return;
}
flags[Dirty::LogicOp] = false;
- const auto& regs = maxwell3d.regs;
+ const auto& regs = maxwell3d->regs;
if (regs.logic_op.enable) {
glEnable(GL_COLOR_LOGIC_OP);
- glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.operation));
+ glLogicOp(MaxwellToGL::LogicOp(regs.logic_op.op));
} else {
glDisable(GL_COLOR_LOGIC_OP);
}
}
void RasterizerOpenGL::SyncScissorTest() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::Scissors] && !flags[VideoCommon::Dirty::RescaleScissors]) {
return;
}
@@ -969,7 +971,7 @@ void RasterizerOpenGL::SyncScissorTest() {
const bool force = flags[VideoCommon::Dirty::RescaleScissors];
flags[VideoCommon::Dirty::RescaleScissors] = false;
- const auto& regs = maxwell3d.regs;
+ const auto& regs = maxwell3d->regs;
const auto& resolution = Settings::values.resolution_info;
const bool is_rescaling{texture_cache.IsRescaling()};
@@ -1005,39 +1007,39 @@ void RasterizerOpenGL::SyncScissorTest() {
}
void RasterizerOpenGL::SyncPointState() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::PointSize]) {
return;
}
flags[Dirty::PointSize] = false;
- oglEnable(GL_POINT_SPRITE, maxwell3d.regs.point_sprite_enable);
- oglEnable(GL_PROGRAM_POINT_SIZE, maxwell3d.regs.vp_point_size.enable);
+ oglEnable(GL_POINT_SPRITE, maxwell3d->regs.point_sprite_enable);
+ oglEnable(GL_PROGRAM_POINT_SIZE, maxwell3d->regs.point_size_attribute.enabled);
const bool is_rescaling{texture_cache.IsRescaling()};
const float scale = is_rescaling ? Settings::values.resolution_info.up_factor : 1.0f;
- glPointSize(std::max(1.0f, maxwell3d.regs.point_size * scale));
+ glPointSize(std::max(1.0f, maxwell3d->regs.point_size * scale));
}
void RasterizerOpenGL::SyncLineState() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::LineWidth]) {
return;
}
flags[Dirty::LineWidth] = false;
- const auto& regs = maxwell3d.regs;
- oglEnable(GL_LINE_SMOOTH, regs.line_smooth_enable);
- glLineWidth(regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased);
+ const auto& regs = maxwell3d->regs;
+ oglEnable(GL_LINE_SMOOTH, regs.line_anti_alias_enable);
+ glLineWidth(regs.line_anti_alias_enable ? regs.line_width_smooth : regs.line_width_aliased);
}
void RasterizerOpenGL::SyncPolygonOffset() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::PolygonOffset]) {
return;
}
flags[Dirty::PolygonOffset] = false;
- const auto& regs = maxwell3d.regs;
+ const auto& regs = maxwell3d->regs;
oglEnable(GL_POLYGON_OFFSET_FILL, regs.polygon_offset_fill_enable);
oglEnable(GL_POLYGON_OFFSET_LINE, regs.polygon_offset_line_enable);
oglEnable(GL_POLYGON_OFFSET_POINT, regs.polygon_offset_point_enable);
@@ -1045,19 +1047,19 @@ void RasterizerOpenGL::SyncPolygonOffset() {
if (regs.polygon_offset_fill_enable || regs.polygon_offset_line_enable ||
regs.polygon_offset_point_enable) {
// Hardware divides polygon offset units by two
- glPolygonOffsetClamp(regs.polygon_offset_factor, regs.polygon_offset_units / 2.0f,
- regs.polygon_offset_clamp);
+ glPolygonOffsetClamp(regs.slope_scale_depth_bias, regs.depth_bias / 2.0f,
+ regs.depth_bias_clamp);
}
}
void RasterizerOpenGL::SyncAlphaTest() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::AlphaTest]) {
return;
}
flags[Dirty::AlphaTest] = false;
- const auto& regs = maxwell3d.regs;
+ const auto& regs = maxwell3d->regs;
if (regs.alpha_test_enabled) {
glEnable(GL_ALPHA_TEST);
glAlphaFunc(MaxwellToGL::ComparisonOp(regs.alpha_test_func), regs.alpha_test_ref);
@@ -1067,25 +1069,25 @@ void RasterizerOpenGL::SyncAlphaTest() {
}
void RasterizerOpenGL::SyncFramebufferSRGB() {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::FramebufferSRGB]) {
return;
}
flags[Dirty::FramebufferSRGB] = false;
- oglEnable(GL_FRAMEBUFFER_SRGB, maxwell3d.regs.framebuffer_srgb);
+ oglEnable(GL_FRAMEBUFFER_SRGB, maxwell3d->regs.framebuffer_srgb);
}
void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum primitive_mode) {
- const auto& regs = maxwell3d.regs;
- if (regs.tfb_enabled == 0) {
+ const auto& regs = maxwell3d->regs;
+ if (regs.transform_feedback_enabled == 0) {
return;
}
program->ConfigureTransformFeedback();
- UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationControl) ||
- regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationEval) ||
- regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::Geometry));
+ UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) ||
+ regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation) ||
+ regs.IsShaderConfigEnabled(Maxwell::ShaderType::Geometry));
UNIMPLEMENTED_IF(primitive_mode != GL_POINTS);
// We may have to call BeginTransformFeedbackNV here since they seem to call different
@@ -1096,11 +1098,58 @@ void RasterizerOpenGL::BeginTransformFeedback(GraphicsPipeline* program, GLenum
}
void RasterizerOpenGL::EndTransformFeedback() {
- if (maxwell3d.regs.tfb_enabled != 0) {
+ if (maxwell3d->regs.transform_feedback_enabled != 0) {
glEndTransformFeedback();
}
}
+void RasterizerOpenGL::InitializeChannel(Tegra::Control::ChannelState& channel) {
+ CreateChannel(channel);
+ {
+ std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ texture_cache.CreateChannel(channel);
+ buffer_cache.CreateChannel(channel);
+ }
+ shader_cache.CreateChannel(channel);
+ query_cache.CreateChannel(channel);
+ state_tracker.SetupTables(channel);
+}
+
+void RasterizerOpenGL::BindChannel(Tegra::Control::ChannelState& channel) {
+ const s32 channel_id = channel.bind_id;
+ BindToChannel(channel_id);
+ {
+ std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ texture_cache.BindToChannel(channel_id);
+ buffer_cache.BindToChannel(channel_id);
+ }
+ shader_cache.BindToChannel(channel_id);
+ query_cache.BindToChannel(channel_id);
+ state_tracker.ChangeChannel(channel);
+ state_tracker.InvalidateState();
+}
+
+void RasterizerOpenGL::ReleaseChannel(s32 channel_id) {
+ EraseChannel(channel_id);
+ {
+ std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ texture_cache.EraseChannel(channel_id);
+ buffer_cache.EraseChannel(channel_id);
+ }
+ shader_cache.EraseChannel(channel_id);
+ query_cache.EraseChannel(channel_id);
+}
+
+void RasterizerOpenGL::BindInlineIndexBuffer() {
+ if (maxwell3d->inline_index_draw_indexes.empty()) {
+ return;
+ }
+ const auto data_count = static_cast<u32>(maxwell3d->inline_index_draw_indexes.size());
+ auto buffer = Buffer(buffer_cache_runtime, *this, 0, data_count);
+ buffer.ImmediateUpload(0, maxwell3d->inline_index_draw_indexes);
+ buffer_cache_runtime.BindIndexBuffer(buffer, 0, data_count);
+}
+
AccelerateDMA::AccelerateDMA(BufferCache& buffer_cache_) : buffer_cache{buffer_cache_} {}
bool AccelerateDMA::BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64 amount) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 31a16fcba..793e0d608 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -12,6 +12,7 @@
#include <glad/glad.h>
#include "common/common_types.h"
+#include "video_core/control/channel_state_cache.h"
#include "video_core/engines/maxwell_dma.h"
#include "video_core/rasterizer_accelerated.h"
#include "video_core/rasterizer_interface.h"
@@ -58,7 +59,8 @@ private:
BufferCache& buffer_cache;
};
-class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
+class RasterizerOpenGL : public VideoCore::RasterizerAccelerated,
+ protected VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo> {
public:
explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
Core::Memory::Memory& cpu_memory_, const Device& device_,
@@ -66,7 +68,7 @@ public:
StateTracker& state_tracker_);
~RasterizerOpenGL() override;
- void Draw(bool is_indexed, bool is_instanced) override;
+ void Draw(bool is_indexed, u32 instance_count) override;
void Clear() override;
void DispatchCompute() override;
void ResetCounter(VideoCore::QueryType type) override;
@@ -78,10 +80,11 @@ public:
bool MustFlushRegion(VAddr addr, u64 size) override;
void InvalidateRegion(VAddr addr, u64 size) override;
void OnCPUWrite(VAddr addr, u64 size) override;
- void SyncGuestHost() override;
+ void InvalidateGPUCache() override;
void UnmapMemory(VAddr addr, u64 size) override;
- void ModifyGPUMemory(GPUVAddr addr, u64 size) override;
- void SignalSemaphore(GPUVAddr addr, u32 value) override;
+ void ModifyGPUMemory(size_t as_id, GPUVAddr addr, u64 size) override;
+ void SignalFence(std::function<void()>&& func) override;
+ void SyncOperation(std::function<void()>&& func) override;
void SignalSyncPoint(u32 value) override;
void SignalReference() override;
void ReleaseFences() override;
@@ -96,7 +99,7 @@ public:
const Tegra::Engines::Fermi2D::Config& copy_config) override;
Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override;
void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
- std::span<u8> memory) override;
+ std::span<const u8> memory) override;
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
u32 pixel_stride) override;
void LoadDiskResources(u64 title_id, std::stop_token stop_loading,
@@ -107,6 +110,12 @@ public:
return num_queued_commands > 0;
}
+ void InitializeChannel(Tegra::Control::ChannelState& channel) override;
+
+ void BindChannel(Tegra::Control::ChannelState& channel) override;
+
+ void ReleaseChannel(s32 channel_id) override;
+
private:
static constexpr size_t MAX_TEXTURES = 192;
static constexpr size_t MAX_IMAGES = 48;
@@ -190,10 +199,9 @@ private:
/// End a transform feedback
void EndTransformFeedback();
+ void BindInlineIndexBuffer();
+
Tegra::GPU& gpu;
- Tegra::Engines::Maxwell3D& maxwell3d;
- Tegra::Engines::KeplerCompute& kepler_compute;
- Tegra::MemoryManager& gpu_memory;
const Device& device;
ScreenInfo& screen_info;
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 7e76f679f..977709518 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -63,6 +63,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
Shader::RuntimeInfo info;
if (previous_program) {
info.previous_stage_stores = previous_program->info.stores;
+ info.previous_stage_legacy_stores_mapping = previous_program->info.legacy_stores_mapping;
} else {
// Mark all stores as available for vertex shaders
info.previous_stage_stores.mask.set();
@@ -78,11 +79,11 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
info.tess_clockwise = key.tessellation_clockwise != 0;
info.tess_primitive = [&key] {
switch (key.tessellation_primitive) {
- case Maxwell::TessellationPrimitive::Isolines:
+ case Maxwell::Tessellation::DomainType::Isolines:
return Shader::TessPrimitive::Isolines;
- case Maxwell::TessellationPrimitive::Triangles:
+ case Maxwell::Tessellation::DomainType::Triangles:
return Shader::TessPrimitive::Triangles;
- case Maxwell::TessellationPrimitive::Quads:
+ case Maxwell::Tessellation::DomainType::Quads:
return Shader::TessPrimitive::Quads;
}
ASSERT(false);
@@ -90,11 +91,11 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
}();
info.tess_spacing = [&] {
switch (key.tessellation_spacing) {
- case Maxwell::TessellationSpacing::Equal:
+ case Maxwell::Tessellation::Spacing::Integer:
return Shader::TessSpacing::Equal;
- case Maxwell::TessellationSpacing::FractionalOdd:
+ case Maxwell::Tessellation::Spacing::FractionalOdd:
return Shader::TessSpacing::FractionalOdd;
- case Maxwell::TessellationSpacing::FractionalEven:
+ case Maxwell::Tessellation::Spacing::FractionalEven:
return Shader::TessSpacing::FractionalEven;
}
ASSERT(false);
@@ -139,28 +140,26 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
}
void SetXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) {
- std::ranges::transform(regs.tfb_layouts, state.layouts.begin(), [](const auto& layout) {
- return VideoCommon::TransformFeedbackState::Layout{
- .stream = layout.stream,
- .varying_count = layout.varying_count,
- .stride = layout.stride,
- };
- });
- state.varyings = regs.tfb_varying_locs;
+ std::ranges::transform(regs.transform_feedback.controls, state.layouts.begin(),
+ [](const auto& layout) {
+ return VideoCommon::TransformFeedbackState::Layout{
+ .stream = layout.stream,
+ .varying_count = layout.varying_count,
+ .stride = layout.stride,
+ };
+ });
+ state.varyings = regs.stream_out_layout;
}
} // Anonymous namespace
ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_,
- Tegra::Engines::Maxwell3D& maxwell3d_,
- Tegra::Engines::KeplerCompute& kepler_compute_,
- Tegra::MemoryManager& gpu_memory_, const Device& device_,
- TextureCache& texture_cache_, BufferCache& buffer_cache_,
- ProgramManager& program_manager_, StateTracker& state_tracker_,
- VideoCore::ShaderNotify& shader_notify_)
- : VideoCommon::ShaderCache{rasterizer_, gpu_memory_, maxwell3d_, kepler_compute_},
- emu_window{emu_window_}, device{device_}, texture_cache{texture_cache_},
- buffer_cache{buffer_cache_}, program_manager{program_manager_}, state_tracker{state_tracker_},
- shader_notify{shader_notify_}, use_asynchronous_shaders{device.UseAsynchronousShaders()},
+ const Device& device_, TextureCache& texture_cache_,
+ BufferCache& buffer_cache_, ProgramManager& program_manager_,
+ StateTracker& state_tracker_, VideoCore::ShaderNotify& shader_notify_)
+ : VideoCommon::ShaderCache{rasterizer_}, emu_window{emu_window_}, device{device_},
+ texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, program_manager{program_manager_},
+ state_tracker{state_tracker_}, shader_notify{shader_notify_},
+ use_asynchronous_shaders{device.UseAsynchronousShaders()},
profile{
.supported_spirv = 0x00010000,
@@ -310,16 +309,18 @@ GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() {
current_pipeline = nullptr;
return nullptr;
}
- const auto& regs{maxwell3d.regs};
+ const auto& regs{maxwell3d->regs};
graphics_key.raw = 0;
- graphics_key.early_z.Assign(regs.force_early_fragment_tests != 0 ? 1 : 0);
+ graphics_key.early_z.Assign(regs.mandated_early_z != 0 ? 1 : 0);
graphics_key.gs_input_topology.Assign(graphics_key.unique_hashes[4] != 0
? regs.draw.topology.Value()
: Maxwell::PrimitiveTopology{});
- graphics_key.tessellation_primitive.Assign(regs.tess_mode.prim.Value());
- graphics_key.tessellation_spacing.Assign(regs.tess_mode.spacing.Value());
- graphics_key.tessellation_clockwise.Assign(regs.tess_mode.cw.Value());
- graphics_key.xfb_enabled.Assign(regs.tfb_enabled != 0 ? 1 : 0);
+ graphics_key.tessellation_primitive.Assign(regs.tessellation.params.domain_type.Value());
+ graphics_key.tessellation_spacing.Assign(regs.tessellation.params.spacing.Value());
+ graphics_key.tessellation_clockwise.Assign(
+ regs.tessellation.params.output_primitives.Value() ==
+ Maxwell::Tessellation::OutputPrimitives::Triangles_CW);
+ graphics_key.xfb_enabled.Assign(regs.transform_feedback_enabled != 0 ? 1 : 0);
if (graphics_key.xfb_enabled) {
SetXfbState(graphics_key.xfb_state, regs);
}
@@ -351,13 +352,13 @@ GraphicsPipeline* ShaderCache::BuiltPipeline(GraphicsPipeline* pipeline) const n
}
// If something is using depth, we can assume that games are not rendering anything which
// will be used one time.
- if (maxwell3d.regs.zeta_enable) {
+ if (maxwell3d->regs.zeta_enable) {
return nullptr;
}
// If games are using a small index count, we can assume these are full screen quads.
// Usually these shaders are only used once for building textures so we can assume they
// can't be built async
- if (maxwell3d.regs.index_array.count <= 6 || maxwell3d.regs.vertex_buffer.count <= 6) {
+ if (maxwell3d->regs.index_buffer.count <= 6 || maxwell3d->regs.vertex_buffer.count <= 6) {
return pipeline;
}
return nullptr;
@@ -368,7 +369,7 @@ ComputePipeline* ShaderCache::CurrentComputePipeline() {
if (!shader) {
return nullptr;
}
- const auto& qmd{kepler_compute.launch_description};
+ const auto& qmd{kepler_compute->launch_description};
const ComputePipelineKey key{
.unique_hash = shader->unique_hash,
.shared_memory_size = qmd.shared_alloc,
@@ -480,9 +481,9 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
previous_program = &program;
}
auto* const thread_worker{build_in_parallel ? workers.get() : nullptr};
- return std::make_unique<GraphicsPipeline>(
- device, texture_cache, buffer_cache, gpu_memory, maxwell3d, program_manager, state_tracker,
- thread_worker, &shader_notify, sources, sources_spirv, infos, key);
+ return std::make_unique<GraphicsPipeline>(device, texture_cache, buffer_cache, program_manager,
+ state_tracker, thread_worker, &shader_notify, sources,
+ sources_spirv, infos, key);
} catch (Shader::Exception& exception) {
LOG_ERROR(Render_OpenGL, "{}", exception.what());
@@ -491,9 +492,9 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
const ComputePipelineKey& key, const VideoCommon::ShaderInfo* shader) {
- const GPUVAddr program_base{kepler_compute.regs.code_loc.Address()};
- const auto& qmd{kepler_compute.launch_description};
- ComputeEnvironment env{kepler_compute, gpu_memory, program_base, qmd.program_start};
+ const GPUVAddr program_base{kepler_compute->regs.code_loc.Address()};
+ const auto& qmd{kepler_compute->launch_description};
+ ComputeEnvironment env{*kepler_compute, *gpu_memory, program_base, qmd.program_start};
env.SetCachedSize(shader->size_bytes);
main_pools.ReleaseContents();
@@ -536,9 +537,8 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
break;
}
- return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, gpu_memory,
- kepler_compute, program_manager, program.info, code,
- code_spirv);
+ return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, program_manager,
+ program.info, code, code_spirv);
} catch (Shader::Exception& exception) {
LOG_ERROR(Render_OpenGL, "{}", exception.what());
return nullptr;
@@ -546,7 +546,7 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
std::unique_ptr<ShaderWorker> ShaderCache::CreateWorkers() const {
return std::make_unique<ShaderWorker>(std::max(std::thread::hardware_concurrency(), 2U) - 1,
- "yuzu:ShaderBuilder",
+ "GlShaderBuilder",
[this] { return Context{emu_window}; });
}
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h
index a14269dea..89f181fe3 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_cache.h
@@ -30,12 +30,9 @@ using ShaderWorker = Common::StatefulThreadWorker<ShaderContext::Context>;
class ShaderCache : public VideoCommon::ShaderCache {
public:
explicit ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindow& emu_window_,
- Tegra::Engines::Maxwell3D& maxwell3d_,
- Tegra::Engines::KeplerCompute& kepler_compute_,
- Tegra::MemoryManager& gpu_memory_, const Device& device_,
- TextureCache& texture_cache_, BufferCache& buffer_cache_,
- ProgramManager& program_manager_, StateTracker& state_tracker_,
- VideoCore::ShaderNotify& shader_notify_);
+ const Device& device_, TextureCache& texture_cache_,
+ BufferCache& buffer_cache_, ProgramManager& program_manager_,
+ StateTracker& state_tracker_, VideoCore::ShaderNotify& shader_notify_);
~ShaderCache();
void LoadDiskResources(u64 title_id, std::stop_token stop_loading,
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp
index 912725ef7..a359f96f1 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.cpp
+++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp
@@ -7,8 +7,8 @@
#include "common/common_types.h"
#include "core/core.h"
+#include "video_core/control/channel_state.h"
#include "video_core/engines/maxwell_3d.h"
-#include "video_core/gpu.h"
#include "video_core/renderer_opengl/gl_state_tracker.h"
#define OFF(field_name) MAXWELL3D_REG_INDEX(field_name)
@@ -38,12 +38,12 @@ void SetupDirtyColorMasks(Tables& tables) {
void SetupDirtyVertexInstances(Tables& tables) {
static constexpr std::size_t instance_base_offset = 3;
for (std::size_t i = 0; i < Regs::NumVertexArrays; ++i) {
- const std::size_t array_offset = OFF(vertex_array) + i * NUM(vertex_array[0]);
+ const std::size_t array_offset = OFF(vertex_streams) + i * NUM(vertex_streams[0]);
const std::size_t instance_array_offset = array_offset + instance_base_offset;
tables[0][instance_array_offset] = static_cast<u8>(VertexInstance0 + i);
tables[1][instance_array_offset] = VertexInstances;
- const std::size_t instance_offset = OFF(instanced_arrays) + i;
+ const std::size_t instance_offset = OFF(vertex_stream_instances) + i;
tables[0][instance_offset] = static_cast<u8>(VertexInstance0 + i);
tables[1][instance_offset] = VertexInstances;
}
@@ -70,8 +70,8 @@ void SetupDirtyViewports(Tables& tables) {
FillBlock(tables[1], OFF(viewport_transform), NUM(viewport_transform), Viewports);
FillBlock(tables[1], OFF(viewports), NUM(viewports), Viewports);
- tables[0][OFF(viewport_transform_enabled)] = ViewportTransform;
- tables[1][OFF(viewport_transform_enabled)] = Viewports;
+ tables[0][OFF(viewport_scale_offset_enbled)] = ViewportTransform;
+ tables[1][OFF(viewport_scale_offset_enbled)] = Viewports;
}
void SetupDirtyScissors(Tables& tables) {
@@ -88,7 +88,7 @@ void SetupDirtyPolygonModes(Tables& tables) {
tables[1][OFF(polygon_mode_front)] = PolygonModes;
tables[1][OFF(polygon_mode_back)] = PolygonModes;
- tables[0][OFF(fill_rectangle)] = PolygonModes;
+ tables[0][OFF(fill_via_triangle_mode)] = PolygonModes;
}
void SetupDirtyDepthTest(Tables& tables) {
@@ -100,11 +100,11 @@ void SetupDirtyDepthTest(Tables& tables) {
void SetupDirtyStencilTest(Tables& tables) {
static constexpr std::array offsets = {
- OFF(stencil_enable), OFF(stencil_front_func_func), OFF(stencil_front_func_ref),
- OFF(stencil_front_func_mask), OFF(stencil_front_op_fail), OFF(stencil_front_op_zfail),
- OFF(stencil_front_op_zpass), OFF(stencil_front_mask), OFF(stencil_two_side_enable),
- OFF(stencil_back_func_func), OFF(stencil_back_func_ref), OFF(stencil_back_func_mask),
- OFF(stencil_back_op_fail), OFF(stencil_back_op_zfail), OFF(stencil_back_op_zpass),
+ OFF(stencil_enable), OFF(stencil_front_op.func), OFF(stencil_front_ref),
+ OFF(stencil_front_func_mask), OFF(stencil_front_op.fail), OFF(stencil_front_op.zfail),
+ OFF(stencil_front_op.zpass), OFF(stencil_front_mask), OFF(stencil_two_side_enable),
+ OFF(stencil_back_op.func), OFF(stencil_back_ref), OFF(stencil_back_func_mask),
+ OFF(stencil_back_op.fail), OFF(stencil_back_op.zfail), OFF(stencil_back_op.zpass),
OFF(stencil_back_mask)};
for (const auto offset : offsets) {
tables[0][offset] = StencilTest;
@@ -121,15 +121,15 @@ void SetupDirtyAlphaTest(Tables& tables) {
void SetupDirtyBlend(Tables& tables) {
FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendColor);
- tables[0][OFF(independent_blend_enable)] = BlendIndependentEnabled;
+ tables[0][OFF(blend_per_target_enabled)] = BlendIndependentEnabled;
for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) {
- const std::size_t offset = OFF(independent_blend) + i * NUM(independent_blend[0]);
- FillBlock(tables[0], offset, NUM(independent_blend[0]), BlendState0 + i);
+ const std::size_t offset = OFF(blend_per_target) + i * NUM(blend_per_target[0]);
+ FillBlock(tables[0], offset, NUM(blend_per_target[0]), BlendState0 + i);
tables[0][OFF(blend.enable) + i] = static_cast<u8>(BlendState0 + i);
}
- FillBlock(tables[1], OFF(independent_blend), NUM(independent_blend), BlendStates);
+ FillBlock(tables[1], OFF(blend_per_target), NUM(blend_per_target), BlendStates);
FillBlock(tables[1], OFF(blend), NUM(blend), BlendStates);
}
@@ -142,13 +142,14 @@ void SetupDirtyPolygonOffset(Tables& tables) {
table[OFF(polygon_offset_fill_enable)] = PolygonOffset;
table[OFF(polygon_offset_line_enable)] = PolygonOffset;
table[OFF(polygon_offset_point_enable)] = PolygonOffset;
- table[OFF(polygon_offset_factor)] = PolygonOffset;
- table[OFF(polygon_offset_units)] = PolygonOffset;
- table[OFF(polygon_offset_clamp)] = PolygonOffset;
+ table[OFF(slope_scale_depth_bias)] = PolygonOffset;
+ table[OFF(depth_bias)] = PolygonOffset;
+ table[OFF(depth_bias_clamp)] = PolygonOffset;
}
void SetupDirtyMultisampleControl(Tables& tables) {
- FillBlock(tables[0], OFF(multisample_control), NUM(multisample_control), MultisampleControl);
+ FillBlock(tables[0], OFF(anti_alias_alpha_control), NUM(anti_alias_alpha_control),
+ MultisampleControl);
}
void SetupDirtyRasterizeEnable(Tables& tables) {
@@ -168,7 +169,7 @@ void SetupDirtyFragmentClampColor(Tables& tables) {
}
void SetupDirtyPointSize(Tables& tables) {
- tables[0][OFF(vp_point_size)] = PointSize;
+ tables[0][OFF(point_size_attribute)] = PointSize;
tables[0][OFF(point_size)] = PointSize;
tables[0][OFF(point_sprite_enable)] = PointSize;
}
@@ -176,35 +177,34 @@ void SetupDirtyPointSize(Tables& tables) {
void SetupDirtyLineWidth(Tables& tables) {
tables[0][OFF(line_width_smooth)] = LineWidth;
tables[0][OFF(line_width_aliased)] = LineWidth;
- tables[0][OFF(line_smooth_enable)] = LineWidth;
+ tables[0][OFF(line_anti_alias_enable)] = LineWidth;
}
void SetupDirtyClipControl(Tables& tables) {
auto& table = tables[0];
- table[OFF(screen_y_control)] = ClipControl;
+ table[OFF(window_origin)] = ClipControl;
table[OFF(depth_mode)] = ClipControl;
}
void SetupDirtyDepthClampEnabled(Tables& tables) {
- tables[0][OFF(view_volume_clip_control)] = DepthClampEnabled;
+ tables[0][OFF(viewport_clip_control)] = DepthClampEnabled;
}
void SetupDirtyMisc(Tables& tables) {
auto& table = tables[0];
- table[OFF(clip_distance_enabled)] = ClipDistances;
+ table[OFF(user_clip_enable)] = ClipDistances;
- table[OFF(front_face)] = FrontFace;
+ table[OFF(gl_front_face)] = FrontFace;
- table[OFF(cull_test_enabled)] = CullTest;
- table[OFF(cull_face)] = CullTest;
+ table[OFF(gl_cull_test_enabled)] = CullTest;
+ table[OFF(gl_cull_face)] = CullTest;
}
} // Anonymous namespace
-StateTracker::StateTracker(Tegra::GPU& gpu) : flags{gpu.Maxwell3D().dirty.flags} {
- auto& dirty = gpu.Maxwell3D().dirty;
- auto& tables = dirty.tables;
+void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) {
+ auto& tables{channel_state.maxwell_3d->dirty.tables};
SetupDirtyFlags(tables);
SetupDirtyColorMasks(tables);
SetupDirtyViewports(tables);
@@ -230,4 +230,14 @@ StateTracker::StateTracker(Tegra::GPU& gpu) : flags{gpu.Maxwell3D().dirty.flags}
SetupDirtyMisc(tables);
}
+void StateTracker::ChangeChannel(Tegra::Control::ChannelState& channel_state) {
+ flags = &channel_state.maxwell_3d->dirty.flags;
+}
+
+void StateTracker::InvalidateState() {
+ flags->set();
+}
+
+StateTracker::StateTracker() : flags{&default_flags} {}
+
} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h
index 04e024f08..19bcf3f35 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.h
+++ b/src/video_core/renderer_opengl/gl_state_tracker.h
@@ -12,8 +12,10 @@
#include "video_core/engines/maxwell_3d.h"
namespace Tegra {
-class GPU;
+namespace Control {
+struct ChannelState;
}
+} // namespace Tegra
namespace OpenGL {
@@ -83,7 +85,7 @@ static_assert(Last <= std::numeric_limits<u8>::max());
class StateTracker {
public:
- explicit StateTracker(Tegra::GPU& gpu);
+ explicit StateTracker();
void BindIndexBuffer(GLuint new_index_buffer) {
if (index_buffer == new_index_buffer) {
@@ -121,94 +123,107 @@ public:
}
void NotifyScreenDrawVertexArray() {
- flags[OpenGL::Dirty::VertexFormats] = true;
- flags[OpenGL::Dirty::VertexFormat0 + 0] = true;
- flags[OpenGL::Dirty::VertexFormat0 + 1] = true;
+ (*flags)[OpenGL::Dirty::VertexFormats] = true;
+ (*flags)[OpenGL::Dirty::VertexFormat0 + 0] = true;
+ (*flags)[OpenGL::Dirty::VertexFormat0 + 1] = true;
- flags[VideoCommon::Dirty::VertexBuffers] = true;
- flags[VideoCommon::Dirty::VertexBuffer0] = true;
+ (*flags)[VideoCommon::Dirty::VertexBuffers] = true;
+ (*flags)[VideoCommon::Dirty::VertexBuffer0] = true;
- flags[OpenGL::Dirty::VertexInstances] = true;
- flags[OpenGL::Dirty::VertexInstance0 + 0] = true;
- flags[OpenGL::Dirty::VertexInstance0 + 1] = true;
+ (*flags)[OpenGL::Dirty::VertexInstances] = true;
+ (*flags)[OpenGL::Dirty::VertexInstance0 + 0] = true;
+ (*flags)[OpenGL::Dirty::VertexInstance0 + 1] = true;
}
void NotifyPolygonModes() {
- flags[OpenGL::Dirty::PolygonModes] = true;
- flags[OpenGL::Dirty::PolygonModeFront] = true;
- flags[OpenGL::Dirty::PolygonModeBack] = true;
+ (*flags)[OpenGL::Dirty::PolygonModes] = true;
+ (*flags)[OpenGL::Dirty::PolygonModeFront] = true;
+ (*flags)[OpenGL::Dirty::PolygonModeBack] = true;
}
void NotifyViewport0() {
- flags[OpenGL::Dirty::Viewports] = true;
- flags[OpenGL::Dirty::Viewport0] = true;
+ (*flags)[OpenGL::Dirty::Viewports] = true;
+ (*flags)[OpenGL::Dirty::Viewport0] = true;
}
void NotifyScissor0() {
- flags[OpenGL::Dirty::Scissors] = true;
- flags[OpenGL::Dirty::Scissor0] = true;
+ (*flags)[OpenGL::Dirty::Scissors] = true;
+ (*flags)[OpenGL::Dirty::Scissor0] = true;
}
void NotifyColorMask(size_t index) {
- flags[OpenGL::Dirty::ColorMasks] = true;
- flags[OpenGL::Dirty::ColorMask0 + index] = true;
+ (*flags)[OpenGL::Dirty::ColorMasks] = true;
+ (*flags)[OpenGL::Dirty::ColorMask0 + index] = true;
}
void NotifyBlend0() {
- flags[OpenGL::Dirty::BlendStates] = true;
- flags[OpenGL::Dirty::BlendState0] = true;
+ (*flags)[OpenGL::Dirty::BlendStates] = true;
+ (*flags)[OpenGL::Dirty::BlendState0] = true;
}
void NotifyFramebuffer() {
- flags[VideoCommon::Dirty::RenderTargets] = true;
+ (*flags)[VideoCommon::Dirty::RenderTargets] = true;
}
void NotifyFrontFace() {
- flags[OpenGL::Dirty::FrontFace] = true;
+ (*flags)[OpenGL::Dirty::FrontFace] = true;
}
void NotifyCullTest() {
- flags[OpenGL::Dirty::CullTest] = true;
+ (*flags)[OpenGL::Dirty::CullTest] = true;
}
void NotifyDepthMask() {
- flags[OpenGL::Dirty::DepthMask] = true;
+ (*flags)[OpenGL::Dirty::DepthMask] = true;
}
void NotifyDepthTest() {
- flags[OpenGL::Dirty::DepthTest] = true;
+ (*flags)[OpenGL::Dirty::DepthTest] = true;
}
void NotifyStencilTest() {
- flags[OpenGL::Dirty::StencilTest] = true;
+ (*flags)[OpenGL::Dirty::StencilTest] = true;
}
void NotifyPolygonOffset() {
- flags[OpenGL::Dirty::PolygonOffset] = true;
+ (*flags)[OpenGL::Dirty::PolygonOffset] = true;
}
void NotifyRasterizeEnable() {
- flags[OpenGL::Dirty::RasterizeEnable] = true;
+ (*flags)[OpenGL::Dirty::RasterizeEnable] = true;
}
void NotifyFramebufferSRGB() {
- flags[OpenGL::Dirty::FramebufferSRGB] = true;
+ (*flags)[OpenGL::Dirty::FramebufferSRGB] = true;
}
void NotifyLogicOp() {
- flags[OpenGL::Dirty::LogicOp] = true;
+ (*flags)[OpenGL::Dirty::LogicOp] = true;
}
void NotifyClipControl() {
- flags[OpenGL::Dirty::ClipControl] = true;
+ (*flags)[OpenGL::Dirty::ClipControl] = true;
}
void NotifyAlphaTest() {
- flags[OpenGL::Dirty::AlphaTest] = true;
+ (*flags)[OpenGL::Dirty::AlphaTest] = true;
}
+ void NotifyRange(u8 start, u8 end) {
+ for (auto flag = start; flag <= end; flag++) {
+ (*flags)[flag] = true;
+ }
+ }
+
+ void SetupTables(Tegra::Control::ChannelState& channel_state);
+
+ void ChangeChannel(Tegra::Control::ChannelState& channel_state);
+
+ void InvalidateState();
+
private:
- Tegra::Engines::Maxwell3D::DirtyState::Flags& flags;
+ Tegra::Engines::Maxwell3D::DirtyState::Flags* flags;
+ Tegra::Engines::Maxwell3D::DirtyState::Flags default_flags{};
GLuint framebuffer = 0;
GLuint index_buffer = 0;
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index 9a72d0d6d..e14f9b2db 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -87,7 +87,7 @@ constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> FORMAT_TAB
{GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}, // BC3_SRGB
{GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM}, // BC7_SRGB
{GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV}, // A4B4G4R4_UNORM
- {GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R4G4_UNORM
+ {GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // G4R4_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR}, // ASTC_2D_4X4_SRGB
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR}, // ASTC_2D_8X8_SRGB
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR}, // ASTC_2D_8X5_SRGB
@@ -99,6 +99,8 @@ constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> FORMAT_TAB
{GL_COMPRESSED_RGBA_ASTC_6x6_KHR}, // ASTC_2D_6X6_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR}, // ASTC_2D_6X6_SRGB
{GL_COMPRESSED_RGBA_ASTC_10x6_KHR}, // ASTC_2D_10X6_UNORM
+ {GL_COMPRESSED_RGBA_ASTC_10x5_KHR}, // ASTC_2D_10X5_UNORM
+ {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR}, // ASTC_2D_10X5_SRGB
{GL_COMPRESSED_RGBA_ASTC_10x10_KHR}, // ASTC_2D_10X10_UNORM
{GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR}, // ASTC_2D_10X10_SRGB
{GL_COMPRESSED_RGBA_ASTC_12x12_KHR}, // ASTC_2D_12X12_UNORM
@@ -124,51 +126,60 @@ inline const FormatTuple& GetFormatTuple(VideoCore::Surface::PixelFormat pixel_f
inline GLenum VertexFormat(Maxwell::VertexAttribute attrib) {
switch (attrib.type) {
- case Maxwell::VertexAttribute::Type::UnsignedNorm:
- case Maxwell::VertexAttribute::Type::UnsignedScaled:
- case Maxwell::VertexAttribute::Type::UnsignedInt:
+ case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway:
+ ASSERT_MSG(false, "Invalid vertex attribute type!");
+ break;
+ case Maxwell::VertexAttribute::Type::UNorm:
+ case Maxwell::VertexAttribute::Type::UScaled:
+ case Maxwell::VertexAttribute::Type::UInt:
switch (attrib.size) {
- case Maxwell::VertexAttribute::Size::Size_8:
- case Maxwell::VertexAttribute::Size::Size_8_8:
- case Maxwell::VertexAttribute::Size::Size_8_8_8:
- case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8:
+ case Maxwell::VertexAttribute::Size::Size_A8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8:
+ case Maxwell::VertexAttribute::Size::Size_G8_R8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
+ case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
return GL_UNSIGNED_BYTE;
- case Maxwell::VertexAttribute::Size::Size_16:
- case Maxwell::VertexAttribute::Size::Size_16_16:
- case Maxwell::VertexAttribute::Size::Size_16_16_16:
- case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
return GL_UNSIGNED_SHORT;
- case Maxwell::VertexAttribute::Size::Size_32:
- case Maxwell::VertexAttribute::Size::Size_32_32:
- case Maxwell::VertexAttribute::Size::Size_32_32_32:
- case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
+ case Maxwell::VertexAttribute::Size::Size_R32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
return GL_UNSIGNED_INT;
- case Maxwell::VertexAttribute::Size::Size_10_10_10_2:
+ case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
return GL_UNSIGNED_INT_2_10_10_10_REV;
default:
break;
}
break;
- case Maxwell::VertexAttribute::Type::SignedNorm:
- case Maxwell::VertexAttribute::Type::SignedScaled:
- case Maxwell::VertexAttribute::Type::SignedInt:
+ case Maxwell::VertexAttribute::Type::SNorm:
+ case Maxwell::VertexAttribute::Type::SScaled:
+ case Maxwell::VertexAttribute::Type::SInt:
switch (attrib.size) {
- case Maxwell::VertexAttribute::Size::Size_8:
- case Maxwell::VertexAttribute::Size::Size_8_8:
- case Maxwell::VertexAttribute::Size::Size_8_8_8:
- case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8:
+ case Maxwell::VertexAttribute::Size::Size_A8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8:
+ case Maxwell::VertexAttribute::Size::Size_G8_R8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
+ case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
return GL_BYTE;
- case Maxwell::VertexAttribute::Size::Size_16:
- case Maxwell::VertexAttribute::Size::Size_16_16:
- case Maxwell::VertexAttribute::Size::Size_16_16_16:
- case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
return GL_SHORT;
- case Maxwell::VertexAttribute::Size::Size_32:
- case Maxwell::VertexAttribute::Size::Size_32_32:
- case Maxwell::VertexAttribute::Size::Size_32_32_32:
- case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
+ case Maxwell::VertexAttribute::Size::Size_R32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
return GL_INT;
- case Maxwell::VertexAttribute::Size::Size_10_10_10_2:
+ case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
return GL_INT_2_10_10_10_REV;
default:
break;
@@ -176,17 +187,17 @@ inline GLenum VertexFormat(Maxwell::VertexAttribute attrib) {
break;
case Maxwell::VertexAttribute::Type::Float:
switch (attrib.size) {
- case Maxwell::VertexAttribute::Size::Size_16:
- case Maxwell::VertexAttribute::Size::Size_16_16:
- case Maxwell::VertexAttribute::Size::Size_16_16_16:
- case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
return GL_HALF_FLOAT;
- case Maxwell::VertexAttribute::Size::Size_32:
- case Maxwell::VertexAttribute::Size::Size_32_32:
- case Maxwell::VertexAttribute::Size::Size_32_32_32:
- case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
+ case Maxwell::VertexAttribute::Size::Size_R32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
return GL_FLOAT;
- case Maxwell::VertexAttribute::Size::Size_11_11_10:
+ case Maxwell::VertexAttribute::Size::Size_B10_G11_R11:
return GL_UNSIGNED_INT_10F_11F_11F_REV;
default:
break;
@@ -333,20 +344,20 @@ inline GLenum DepthCompareFunc(Tegra::Texture::DepthCompareFunc func) {
inline GLenum BlendEquation(Maxwell::Blend::Equation equation) {
switch (equation) {
- case Maxwell::Blend::Equation::Add:
- case Maxwell::Blend::Equation::AddGL:
+ case Maxwell::Blend::Equation::Add_D3D:
+ case Maxwell::Blend::Equation::Add_GL:
return GL_FUNC_ADD;
- case Maxwell::Blend::Equation::Subtract:
- case Maxwell::Blend::Equation::SubtractGL:
+ case Maxwell::Blend::Equation::Subtract_D3D:
+ case Maxwell::Blend::Equation::Subtract_GL:
return GL_FUNC_SUBTRACT;
- case Maxwell::Blend::Equation::ReverseSubtract:
- case Maxwell::Blend::Equation::ReverseSubtractGL:
+ case Maxwell::Blend::Equation::ReverseSubtract_D3D:
+ case Maxwell::Blend::Equation::ReverseSubtract_GL:
return GL_FUNC_REVERSE_SUBTRACT;
- case Maxwell::Blend::Equation::Min:
- case Maxwell::Blend::Equation::MinGL:
+ case Maxwell::Blend::Equation::Min_D3D:
+ case Maxwell::Blend::Equation::Min_GL:
return GL_MIN;
- case Maxwell::Blend::Equation::Max:
- case Maxwell::Blend::Equation::MaxGL:
+ case Maxwell::Blend::Equation::Max_D3D:
+ case Maxwell::Blend::Equation::Max_GL:
return GL_MAX;
}
UNIMPLEMENTED_MSG("Unimplemented blend equation={}", equation);
@@ -355,62 +366,62 @@ inline GLenum BlendEquation(Maxwell::Blend::Equation equation) {
inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
switch (factor) {
- case Maxwell::Blend::Factor::Zero:
- case Maxwell::Blend::Factor::ZeroGL:
+ case Maxwell::Blend::Factor::Zero_D3D:
+ case Maxwell::Blend::Factor::Zero_GL:
return GL_ZERO;
- case Maxwell::Blend::Factor::One:
- case Maxwell::Blend::Factor::OneGL:
+ case Maxwell::Blend::Factor::One_D3D:
+ case Maxwell::Blend::Factor::One_GL:
return GL_ONE;
- case Maxwell::Blend::Factor::SourceColor:
- case Maxwell::Blend::Factor::SourceColorGL:
+ case Maxwell::Blend::Factor::SourceColor_D3D:
+ case Maxwell::Blend::Factor::SourceColor_GL:
return GL_SRC_COLOR;
- case Maxwell::Blend::Factor::OneMinusSourceColor:
- case Maxwell::Blend::Factor::OneMinusSourceColorGL:
+ case Maxwell::Blend::Factor::OneMinusSourceColor_D3D:
+ case Maxwell::Blend::Factor::OneMinusSourceColor_GL:
return GL_ONE_MINUS_SRC_COLOR;
- case Maxwell::Blend::Factor::SourceAlpha:
- case Maxwell::Blend::Factor::SourceAlphaGL:
+ case Maxwell::Blend::Factor::SourceAlpha_D3D:
+ case Maxwell::Blend::Factor::SourceAlpha_GL:
return GL_SRC_ALPHA;
- case Maxwell::Blend::Factor::OneMinusSourceAlpha:
- case Maxwell::Blend::Factor::OneMinusSourceAlphaGL:
+ case Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D:
+ case Maxwell::Blend::Factor::OneMinusSourceAlpha_GL:
return GL_ONE_MINUS_SRC_ALPHA;
- case Maxwell::Blend::Factor::DestAlpha:
- case Maxwell::Blend::Factor::DestAlphaGL:
+ case Maxwell::Blend::Factor::DestAlpha_D3D:
+ case Maxwell::Blend::Factor::DestAlpha_GL:
return GL_DST_ALPHA;
- case Maxwell::Blend::Factor::OneMinusDestAlpha:
- case Maxwell::Blend::Factor::OneMinusDestAlphaGL:
+ case Maxwell::Blend::Factor::OneMinusDestAlpha_D3D:
+ case Maxwell::Blend::Factor::OneMinusDestAlpha_GL:
return GL_ONE_MINUS_DST_ALPHA;
- case Maxwell::Blend::Factor::DestColor:
- case Maxwell::Blend::Factor::DestColorGL:
+ case Maxwell::Blend::Factor::DestColor_D3D:
+ case Maxwell::Blend::Factor::DestColor_GL:
return GL_DST_COLOR;
- case Maxwell::Blend::Factor::OneMinusDestColor:
- case Maxwell::Blend::Factor::OneMinusDestColorGL:
+ case Maxwell::Blend::Factor::OneMinusDestColor_D3D:
+ case Maxwell::Blend::Factor::OneMinusDestColor_GL:
return GL_ONE_MINUS_DST_COLOR;
- case Maxwell::Blend::Factor::SourceAlphaSaturate:
- case Maxwell::Blend::Factor::SourceAlphaSaturateGL:
+ case Maxwell::Blend::Factor::SourceAlphaSaturate_D3D:
+ case Maxwell::Blend::Factor::SourceAlphaSaturate_GL:
return GL_SRC_ALPHA_SATURATE;
- case Maxwell::Blend::Factor::Source1Color:
- case Maxwell::Blend::Factor::Source1ColorGL:
+ case Maxwell::Blend::Factor::Source1Color_D3D:
+ case Maxwell::Blend::Factor::Source1Color_GL:
return GL_SRC1_COLOR;
- case Maxwell::Blend::Factor::OneMinusSource1Color:
- case Maxwell::Blend::Factor::OneMinusSource1ColorGL:
+ case Maxwell::Blend::Factor::OneMinusSource1Color_D3D:
+ case Maxwell::Blend::Factor::OneMinusSource1Color_GL:
return GL_ONE_MINUS_SRC1_COLOR;
- case Maxwell::Blend::Factor::Source1Alpha:
- case Maxwell::Blend::Factor::Source1AlphaGL:
+ case Maxwell::Blend::Factor::Source1Alpha_D3D:
+ case Maxwell::Blend::Factor::Source1Alpha_GL:
return GL_SRC1_ALPHA;
- case Maxwell::Blend::Factor::OneMinusSource1Alpha:
- case Maxwell::Blend::Factor::OneMinusSource1AlphaGL:
+ case Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D:
+ case Maxwell::Blend::Factor::OneMinusSource1Alpha_GL:
return GL_ONE_MINUS_SRC1_ALPHA;
- case Maxwell::Blend::Factor::ConstantColor:
- case Maxwell::Blend::Factor::ConstantColorGL:
+ case Maxwell::Blend::Factor::BlendFactor_D3D:
+ case Maxwell::Blend::Factor::ConstantColor_GL:
return GL_CONSTANT_COLOR;
- case Maxwell::Blend::Factor::OneMinusConstantColor:
- case Maxwell::Blend::Factor::OneMinusConstantColorGL:
+ case Maxwell::Blend::Factor::OneMinusBlendFactor_D3D:
+ case Maxwell::Blend::Factor::OneMinusConstantColor_GL:
return GL_ONE_MINUS_CONSTANT_COLOR;
- case Maxwell::Blend::Factor::ConstantAlpha:
- case Maxwell::Blend::Factor::ConstantAlphaGL:
+ case Maxwell::Blend::Factor::BothSourceAlpha_D3D:
+ case Maxwell::Blend::Factor::ConstantAlpha_GL:
return GL_CONSTANT_ALPHA;
- case Maxwell::Blend::Factor::OneMinusConstantAlpha:
- case Maxwell::Blend::Factor::OneMinusConstantAlphaGL:
+ case Maxwell::Blend::Factor::OneMinusBothSourceAlpha_D3D:
+ case Maxwell::Blend::Factor::OneMinusConstantAlpha_GL:
return GL_ONE_MINUS_CONSTANT_ALPHA;
}
UNIMPLEMENTED_MSG("Unimplemented blend factor={}", factor);
@@ -419,60 +430,60 @@ inline GLenum BlendFunc(Maxwell::Blend::Factor factor) {
inline GLenum ComparisonOp(Maxwell::ComparisonOp comparison) {
switch (comparison) {
- case Maxwell::ComparisonOp::Never:
- case Maxwell::ComparisonOp::NeverOld:
+ case Maxwell::ComparisonOp::Never_D3D:
+ case Maxwell::ComparisonOp::Never_GL:
return GL_NEVER;
- case Maxwell::ComparisonOp::Less:
- case Maxwell::ComparisonOp::LessOld:
+ case Maxwell::ComparisonOp::Less_D3D:
+ case Maxwell::ComparisonOp::Less_GL:
return GL_LESS;
- case Maxwell::ComparisonOp::Equal:
- case Maxwell::ComparisonOp::EqualOld:
+ case Maxwell::ComparisonOp::Equal_D3D:
+ case Maxwell::ComparisonOp::Equal_GL:
return GL_EQUAL;
- case Maxwell::ComparisonOp::LessEqual:
- case Maxwell::ComparisonOp::LessEqualOld:
+ case Maxwell::ComparisonOp::LessEqual_D3D:
+ case Maxwell::ComparisonOp::LessEqual_GL:
return GL_LEQUAL;
- case Maxwell::ComparisonOp::Greater:
- case Maxwell::ComparisonOp::GreaterOld:
+ case Maxwell::ComparisonOp::Greater_D3D:
+ case Maxwell::ComparisonOp::Greater_GL:
return GL_GREATER;
- case Maxwell::ComparisonOp::NotEqual:
- case Maxwell::ComparisonOp::NotEqualOld:
+ case Maxwell::ComparisonOp::NotEqual_D3D:
+ case Maxwell::ComparisonOp::NotEqual_GL:
return GL_NOTEQUAL;
- case Maxwell::ComparisonOp::GreaterEqual:
- case Maxwell::ComparisonOp::GreaterEqualOld:
+ case Maxwell::ComparisonOp::GreaterEqual_D3D:
+ case Maxwell::ComparisonOp::GreaterEqual_GL:
return GL_GEQUAL;
- case Maxwell::ComparisonOp::Always:
- case Maxwell::ComparisonOp::AlwaysOld:
+ case Maxwell::ComparisonOp::Always_D3D:
+ case Maxwell::ComparisonOp::Always_GL:
return GL_ALWAYS;
}
UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison);
return GL_ALWAYS;
}
-inline GLenum StencilOp(Maxwell::StencilOp stencil) {
+inline GLenum StencilOp(Maxwell::StencilOp::Op stencil) {
switch (stencil) {
- case Maxwell::StencilOp::Keep:
- case Maxwell::StencilOp::KeepOGL:
+ case Maxwell::StencilOp::Op::Keep_D3D:
+ case Maxwell::StencilOp::Op::Keep_GL:
return GL_KEEP;
- case Maxwell::StencilOp::Zero:
- case Maxwell::StencilOp::ZeroOGL:
+ case Maxwell::StencilOp::Op::Zero_D3D:
+ case Maxwell::StencilOp::Op::Zero_GL:
return GL_ZERO;
- case Maxwell::StencilOp::Replace:
- case Maxwell::StencilOp::ReplaceOGL:
+ case Maxwell::StencilOp::Op::Replace_D3D:
+ case Maxwell::StencilOp::Op::Replace_GL:
return GL_REPLACE;
- case Maxwell::StencilOp::Incr:
- case Maxwell::StencilOp::IncrOGL:
+ case Maxwell::StencilOp::Op::IncrSaturate_D3D:
+ case Maxwell::StencilOp::Op::IncrSaturate_GL:
return GL_INCR;
- case Maxwell::StencilOp::Decr:
- case Maxwell::StencilOp::DecrOGL:
+ case Maxwell::StencilOp::Op::DecrSaturate_D3D:
+ case Maxwell::StencilOp::Op::DecrSaturate_GL:
return GL_DECR;
- case Maxwell::StencilOp::Invert:
- case Maxwell::StencilOp::InvertOGL:
+ case Maxwell::StencilOp::Op::Invert_D3D:
+ case Maxwell::StencilOp::Op::Invert_GL:
return GL_INVERT;
- case Maxwell::StencilOp::IncrWrap:
- case Maxwell::StencilOp::IncrWrapOGL:
+ case Maxwell::StencilOp::Op::Incr_D3D:
+ case Maxwell::StencilOp::Op::Incr_GL:
return GL_INCR_WRAP;
- case Maxwell::StencilOp::DecrWrap:
- case Maxwell::StencilOp::DecrWrapOGL:
+ case Maxwell::StencilOp::Op::Decr_D3D:
+ case Maxwell::StencilOp::Op::Decr_GL:
return GL_DECR_WRAP;
}
UNIMPLEMENTED_MSG("Unimplemented stencil op={}", stencil);
@@ -503,39 +514,39 @@ inline GLenum CullFace(Maxwell::CullFace cull_face) {
return GL_BACK;
}
-inline GLenum LogicOp(Maxwell::LogicOperation operation) {
+inline GLenum LogicOp(Maxwell::LogicOp::Op operation) {
switch (operation) {
- case Maxwell::LogicOperation::Clear:
+ case Maxwell::LogicOp::Op::Clear:
return GL_CLEAR;
- case Maxwell::LogicOperation::And:
+ case Maxwell::LogicOp::Op::And:
return GL_AND;
- case Maxwell::LogicOperation::AndReverse:
+ case Maxwell::LogicOp::Op::AndReverse:
return GL_AND_REVERSE;
- case Maxwell::LogicOperation::Copy:
+ case Maxwell::LogicOp::Op::Copy:
return GL_COPY;
- case Maxwell::LogicOperation::AndInverted:
+ case Maxwell::LogicOp::Op::AndInverted:
return GL_AND_INVERTED;
- case Maxwell::LogicOperation::NoOp:
+ case Maxwell::LogicOp::Op::NoOp:
return GL_NOOP;
- case Maxwell::LogicOperation::Xor:
+ case Maxwell::LogicOp::Op::Xor:
return GL_XOR;
- case Maxwell::LogicOperation::Or:
+ case Maxwell::LogicOp::Op::Or:
return GL_OR;
- case Maxwell::LogicOperation::Nor:
+ case Maxwell::LogicOp::Op::Nor:
return GL_NOR;
- case Maxwell::LogicOperation::Equiv:
+ case Maxwell::LogicOp::Op::Equiv:
return GL_EQUIV;
- case Maxwell::LogicOperation::Invert:
+ case Maxwell::LogicOp::Op::Invert:
return GL_INVERT;
- case Maxwell::LogicOperation::OrReverse:
+ case Maxwell::LogicOp::Op::OrReverse:
return GL_OR_REVERSE;
- case Maxwell::LogicOperation::CopyInverted:
+ case Maxwell::LogicOp::Op::CopyInverted:
return GL_COPY_INVERTED;
- case Maxwell::LogicOperation::OrInverted:
+ case Maxwell::LogicOp::Op::OrInverted:
return GL_OR_INVERTED;
- case Maxwell::LogicOperation::Nand:
+ case Maxwell::LogicOp::Op::Nand:
return GL_NAND;
- case Maxwell::LogicOperation::Set:
+ case Maxwell::LogicOp::Op::Set:
return GL_SET;
}
UNIMPLEMENTED_MSG("Unimplemented logic operation={}", operation);
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 34f3f7a67..8bd5eba7e 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -131,7 +131,7 @@ RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_,
Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_,
std::unique_ptr<Core::Frontend::GraphicsContext> context_)
: RendererBase{emu_window_, std::move(context_)}, telemetry_session{telemetry_session_},
- emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, state_tracker{gpu},
+ emu_window{emu_window_}, cpu_memory{cpu_memory_}, gpu{gpu_}, state_tracker{},
program_manager{device},
rasterizer(emu_window, gpu, cpu_memory, device, screen_info, program_manager, state_tracker) {
if (Settings::values.renderer_debug && GLAD_GL_KHR_debug) {
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
index 733b454de..f85ed8e5b 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.cpp
@@ -34,14 +34,15 @@ constexpr std::array POLYGON_OFFSET_ENABLE_LUT = {
};
void RefreshXfbState(VideoCommon::TransformFeedbackState& state, const Maxwell& regs) {
- std::ranges::transform(regs.tfb_layouts, state.layouts.begin(), [](const auto& layout) {
- return VideoCommon::TransformFeedbackState::Layout{
- .stream = layout.stream,
- .varying_count = layout.varying_count,
- .stride = layout.stride,
- };
- });
- state.varyings = regs.tfb_varying_locs;
+ std::ranges::transform(regs.transform_feedback.controls, state.layouts.begin(),
+ [](const auto& layout) {
+ return VideoCommon::TransformFeedbackState::Layout{
+ .stream = layout.stream,
+ .varying_count = layout.varying_count,
+ .stride = layout.stride,
+ };
+ });
+ state.varyings = regs.stream_out_layout;
}
} // Anonymous namespace
@@ -58,33 +59,38 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d,
raw1 = 0;
extended_dynamic_state.Assign(has_extended_dynamic_state ? 1 : 0);
dynamic_vertex_input.Assign(has_dynamic_vertex_input ? 1 : 0);
- xfb_enabled.Assign(regs.tfb_enabled != 0);
+ xfb_enabled.Assign(regs.transform_feedback_enabled != 0);
primitive_restart_enable.Assign(regs.primitive_restart.enabled != 0 ? 1 : 0);
depth_bias_enable.Assign(enabled_lut[POLYGON_OFFSET_ENABLE_LUT[topology_index]] != 0 ? 1 : 0);
- depth_clamp_disabled.Assign(regs.view_volume_clip_control.depth_clamp_disabled.Value());
+ depth_clamp_disabled.Assign(regs.viewport_clip_control.geometry_clip ==
+ Maxwell::ViewportClipControl::GeometryClip::Passthrough ||
+ regs.viewport_clip_control.geometry_clip ==
+ Maxwell::ViewportClipControl::GeometryClip::FrustumXYZ ||
+ regs.viewport_clip_control.geometry_clip ==
+ Maxwell::ViewportClipControl::GeometryClip::FrustumZ);
ndc_minus_one_to_one.Assign(regs.depth_mode == Maxwell::DepthMode::MinusOneToOne ? 1 : 0);
polygon_mode.Assign(PackPolygonMode(regs.polygon_mode_front));
patch_control_points_minus_one.Assign(regs.patch_vertices - 1);
- tessellation_primitive.Assign(static_cast<u32>(regs.tess_mode.prim.Value()));
- tessellation_spacing.Assign(static_cast<u32>(regs.tess_mode.spacing.Value()));
- tessellation_clockwise.Assign(regs.tess_mode.cw.Value());
+ tessellation_primitive.Assign(static_cast<u32>(regs.tessellation.params.domain_type.Value()));
+ tessellation_spacing.Assign(static_cast<u32>(regs.tessellation.params.spacing.Value()));
+ tessellation_clockwise.Assign(regs.tessellation.params.output_primitives.Value() ==
+ Maxwell::Tessellation::OutputPrimitives::Triangles_CW);
logic_op_enable.Assign(regs.logic_op.enable != 0 ? 1 : 0);
- logic_op.Assign(PackLogicOp(regs.logic_op.operation));
+ logic_op.Assign(PackLogicOp(regs.logic_op.op));
topology.Assign(regs.draw.topology);
- msaa_mode.Assign(regs.multisample_mode);
+ msaa_mode.Assign(regs.anti_alias_samples_mode);
raw2 = 0;
rasterize_enable.Assign(regs.rasterize_enable != 0 ? 1 : 0);
const auto test_func =
- regs.alpha_test_enabled != 0 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always;
+ regs.alpha_test_enabled != 0 ? regs.alpha_test_func : Maxwell::ComparisonOp::Always_GL;
alpha_test_func.Assign(PackComparisonOp(test_func));
- early_z.Assign(regs.force_early_fragment_tests != 0 ? 1 : 0);
+ early_z.Assign(regs.mandated_early_z != 0 ? 1 : 0);
depth_enabled.Assign(regs.zeta_enable != 0 ? 1 : 0);
depth_format.Assign(static_cast<u32>(regs.zeta.format));
- y_negate.Assign(regs.screen_y_control.y_negate != 0 ? 1 : 0);
- provoking_vertex_last.Assign(regs.provoking_vertex_last != 0 ? 1 : 0);
- conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0);
- smooth_lines.Assign(regs.line_smooth_enable != 0 ? 1 : 0);
+ y_negate.Assign(regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft ? 1 : 0);
+ provoking_vertex_last.Assign(regs.provoking_vertex == Maxwell::ProvokingVertex::Last ? 1 : 0);
+ smooth_lines.Assign(regs.line_anti_alias_enable != 0 ? 1 : 0);
for (size_t i = 0; i < regs.rt.size(); ++i) {
color_formats[i] = static_cast<u8>(regs.rt[i].format);
@@ -116,8 +122,8 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d,
maxwell3d.dirty.flags[Dirty::VertexInput] = false;
enabled_divisors = 0;
for (size_t index = 0; index < Maxwell::NumVertexArrays; ++index) {
- const bool is_enabled = regs.instanced_arrays.IsInstancingEnabled(index);
- binding_divisors[index] = is_enabled ? regs.vertex_array[index].divisor : 0;
+ const bool is_enabled = regs.vertex_stream_instances.IsInstancingEnabled(index);
+ binding_divisors[index] = is_enabled ? regs.vertex_streams[index].frequency : 0;
enabled_divisors |= (is_enabled ? u64{1} : 0) << index;
}
for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
@@ -164,17 +170,17 @@ void FixedPipelineState::BlendingAttachment::Refresh(const Maxwell& regs, size_t
// TODO: C++20 Use templated lambda to deduplicate code
- if (!regs.independent_blend_enable) {
- const auto& src = regs.blend;
- if (!src.enable[index]) {
+ if (!regs.blend_per_target_enabled) {
+ if (!regs.blend.enable[index]) {
return;
}
- equation_rgb.Assign(PackBlendEquation(src.equation_rgb));
- equation_a.Assign(PackBlendEquation(src.equation_a));
- factor_source_rgb.Assign(PackBlendFactor(src.factor_source_rgb));
- factor_dest_rgb.Assign(PackBlendFactor(src.factor_dest_rgb));
- factor_source_a.Assign(PackBlendFactor(src.factor_source_a));
- factor_dest_a.Assign(PackBlendFactor(src.factor_dest_a));
+ const auto& src = regs.blend;
+ equation_rgb.Assign(PackBlendEquation(src.color_op));
+ equation_a.Assign(PackBlendEquation(src.alpha_op));
+ factor_source_rgb.Assign(PackBlendFactor(src.color_source));
+ factor_dest_rgb.Assign(PackBlendFactor(src.color_dest));
+ factor_source_a.Assign(PackBlendFactor(src.alpha_source));
+ factor_dest_a.Assign(PackBlendFactor(src.alpha_dest));
enable.Assign(1);
return;
}
@@ -182,34 +188,34 @@ void FixedPipelineState::BlendingAttachment::Refresh(const Maxwell& regs, size_t
if (!regs.blend.enable[index]) {
return;
}
- const auto& src = regs.independent_blend[index];
- equation_rgb.Assign(PackBlendEquation(src.equation_rgb));
- equation_a.Assign(PackBlendEquation(src.equation_a));
- factor_source_rgb.Assign(PackBlendFactor(src.factor_source_rgb));
- factor_dest_rgb.Assign(PackBlendFactor(src.factor_dest_rgb));
- factor_source_a.Assign(PackBlendFactor(src.factor_source_a));
- factor_dest_a.Assign(PackBlendFactor(src.factor_dest_a));
+ const auto& src = regs.blend_per_target[index];
+ equation_rgb.Assign(PackBlendEquation(src.color_op));
+ equation_a.Assign(PackBlendEquation(src.alpha_op));
+ factor_source_rgb.Assign(PackBlendFactor(src.color_source));
+ factor_dest_rgb.Assign(PackBlendFactor(src.color_dest));
+ factor_source_a.Assign(PackBlendFactor(src.alpha_source));
+ factor_dest_a.Assign(PackBlendFactor(src.alpha_dest));
enable.Assign(1);
}
void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) {
- u32 packed_front_face = PackFrontFace(regs.front_face);
- if (regs.screen_y_control.triangle_rast_flip != 0) {
+ u32 packed_front_face = PackFrontFace(regs.gl_front_face);
+ if (regs.window_origin.flip_y != 0) {
// Flip front face
packed_front_face = 1 - packed_front_face;
}
raw1 = 0;
raw2 = 0;
- front.action_stencil_fail.Assign(PackStencilOp(regs.stencil_front_op_fail));
- front.action_depth_fail.Assign(PackStencilOp(regs.stencil_front_op_zfail));
- front.action_depth_pass.Assign(PackStencilOp(regs.stencil_front_op_zpass));
- front.test_func.Assign(PackComparisonOp(regs.stencil_front_func_func));
+ front.action_stencil_fail.Assign(PackStencilOp(regs.stencil_front_op.fail));
+ front.action_depth_fail.Assign(PackStencilOp(regs.stencil_front_op.zfail));
+ front.action_depth_pass.Assign(PackStencilOp(regs.stencil_front_op.zpass));
+ front.test_func.Assign(PackComparisonOp(regs.stencil_front_op.func));
if (regs.stencil_two_side_enable) {
- back.action_stencil_fail.Assign(PackStencilOp(regs.stencil_back_op_fail));
- back.action_depth_fail.Assign(PackStencilOp(regs.stencil_back_op_zfail));
- back.action_depth_pass.Assign(PackStencilOp(regs.stencil_back_op_zpass));
- back.test_func.Assign(PackComparisonOp(regs.stencil_back_func_func));
+ back.action_stencil_fail.Assign(PackStencilOp(regs.stencil_back_op.fail));
+ back.action_depth_fail.Assign(PackStencilOp(regs.stencil_back_op.zfail));
+ back.action_depth_pass.Assign(PackStencilOp(regs.stencil_back_op.zpass));
+ back.test_func.Assign(PackComparisonOp(regs.stencil_back_op.func));
} else {
back.action_stencil_fail.Assign(front.action_stencil_fail);
back.action_depth_fail.Assign(front.action_depth_fail);
@@ -222,9 +228,9 @@ void FixedPipelineState::DynamicState::Refresh(const Maxwell& regs) {
depth_test_enable.Assign(regs.depth_test_enable);
front_face.Assign(packed_front_face);
depth_test_func.Assign(PackComparisonOp(regs.depth_test_func));
- cull_face.Assign(PackCullFace(regs.cull_face));
- cull_enable.Assign(regs.cull_test_enabled != 0 ? 1 : 0);
- std::ranges::transform(regs.vertex_array, vertex_strides.begin(), [](const auto& array) {
+ cull_face.Assign(PackCullFace(regs.gl_cull_face));
+ cull_enable.Assign(regs.gl_cull_test_enabled != 0 ? 1 : 0);
+ std::ranges::transform(regs.vertex_streams, vertex_strides.begin(), [](const auto& array) {
return static_cast<u16>(array.stride.Value());
});
}
@@ -251,41 +257,42 @@ Maxwell::ComparisonOp FixedPipelineState::UnpackComparisonOp(u32 packed) noexcep
return static_cast<Maxwell::ComparisonOp>(packed + 1);
}
-u32 FixedPipelineState::PackStencilOp(Maxwell::StencilOp op) noexcept {
+u32 FixedPipelineState::PackStencilOp(Maxwell::StencilOp::Op op) noexcept {
switch (op) {
- case Maxwell::StencilOp::Keep:
- case Maxwell::StencilOp::KeepOGL:
+ case Maxwell::StencilOp::Op::Keep_D3D:
+ case Maxwell::StencilOp::Op::Keep_GL:
return 0;
- case Maxwell::StencilOp::Zero:
- case Maxwell::StencilOp::ZeroOGL:
+ case Maxwell::StencilOp::Op::Zero_D3D:
+ case Maxwell::StencilOp::Op::Zero_GL:
return 1;
- case Maxwell::StencilOp::Replace:
- case Maxwell::StencilOp::ReplaceOGL:
+ case Maxwell::StencilOp::Op::Replace_D3D:
+ case Maxwell::StencilOp::Op::Replace_GL:
return 2;
- case Maxwell::StencilOp::Incr:
- case Maxwell::StencilOp::IncrOGL:
+ case Maxwell::StencilOp::Op::IncrSaturate_D3D:
+ case Maxwell::StencilOp::Op::IncrSaturate_GL:
return 3;
- case Maxwell::StencilOp::Decr:
- case Maxwell::StencilOp::DecrOGL:
+ case Maxwell::StencilOp::Op::DecrSaturate_D3D:
+ case Maxwell::StencilOp::Op::DecrSaturate_GL:
return 4;
- case Maxwell::StencilOp::Invert:
- case Maxwell::StencilOp::InvertOGL:
+ case Maxwell::StencilOp::Op::Invert_D3D:
+ case Maxwell::StencilOp::Op::Invert_GL:
return 5;
- case Maxwell::StencilOp::IncrWrap:
- case Maxwell::StencilOp::IncrWrapOGL:
+ case Maxwell::StencilOp::Op::Incr_D3D:
+ case Maxwell::StencilOp::Op::Incr_GL:
return 6;
- case Maxwell::StencilOp::DecrWrap:
- case Maxwell::StencilOp::DecrWrapOGL:
+ case Maxwell::StencilOp::Op::Decr_D3D:
+ case Maxwell::StencilOp::Op::Decr_GL:
return 7;
}
return 0;
}
-Maxwell::StencilOp FixedPipelineState::UnpackStencilOp(u32 packed) noexcept {
- static constexpr std::array LUT = {Maxwell::StencilOp::Keep, Maxwell::StencilOp::Zero,
- Maxwell::StencilOp::Replace, Maxwell::StencilOp::Incr,
- Maxwell::StencilOp::Decr, Maxwell::StencilOp::Invert,
- Maxwell::StencilOp::IncrWrap, Maxwell::StencilOp::DecrWrap};
+Maxwell::StencilOp::Op FixedPipelineState::UnpackStencilOp(u32 packed) noexcept {
+ static constexpr std::array LUT = {
+ Maxwell::StencilOp::Op::Keep_D3D, Maxwell::StencilOp::Op::Zero_D3D,
+ Maxwell::StencilOp::Op::Replace_D3D, Maxwell::StencilOp::Op::IncrSaturate_D3D,
+ Maxwell::StencilOp::Op::DecrSaturate_D3D, Maxwell::StencilOp::Op::Invert_D3D,
+ Maxwell::StencilOp::Op::Incr_D3D, Maxwell::StencilOp::Op::Decr_D3D};
return LUT[packed];
}
@@ -318,30 +325,30 @@ Maxwell::PolygonMode FixedPipelineState::UnpackPolygonMode(u32 packed) noexcept
return static_cast<Maxwell::PolygonMode>(packed + 0x1B00);
}
-u32 FixedPipelineState::PackLogicOp(Maxwell::LogicOperation op) noexcept {
+u32 FixedPipelineState::PackLogicOp(Maxwell::LogicOp::Op op) noexcept {
return static_cast<u32>(op) - 0x1500;
}
-Maxwell::LogicOperation FixedPipelineState::UnpackLogicOp(u32 packed) noexcept {
- return static_cast<Maxwell::LogicOperation>(packed + 0x1500);
+Maxwell::LogicOp::Op FixedPipelineState::UnpackLogicOp(u32 packed) noexcept {
+ return static_cast<Maxwell::LogicOp::Op>(packed + 0x1500);
}
u32 FixedPipelineState::PackBlendEquation(Maxwell::Blend::Equation equation) noexcept {
switch (equation) {
- case Maxwell::Blend::Equation::Add:
- case Maxwell::Blend::Equation::AddGL:
+ case Maxwell::Blend::Equation::Add_D3D:
+ case Maxwell::Blend::Equation::Add_GL:
return 0;
- case Maxwell::Blend::Equation::Subtract:
- case Maxwell::Blend::Equation::SubtractGL:
+ case Maxwell::Blend::Equation::Subtract_D3D:
+ case Maxwell::Blend::Equation::Subtract_GL:
return 1;
- case Maxwell::Blend::Equation::ReverseSubtract:
- case Maxwell::Blend::Equation::ReverseSubtractGL:
+ case Maxwell::Blend::Equation::ReverseSubtract_D3D:
+ case Maxwell::Blend::Equation::ReverseSubtract_GL:
return 2;
- case Maxwell::Blend::Equation::Min:
- case Maxwell::Blend::Equation::MinGL:
+ case Maxwell::Blend::Equation::Min_D3D:
+ case Maxwell::Blend::Equation::Min_GL:
return 3;
- case Maxwell::Blend::Equation::Max:
- case Maxwell::Blend::Equation::MaxGL:
+ case Maxwell::Blend::Equation::Max_D3D:
+ case Maxwell::Blend::Equation::Max_GL:
return 4;
}
return 0;
@@ -349,97 +356,99 @@ u32 FixedPipelineState::PackBlendEquation(Maxwell::Blend::Equation equation) noe
Maxwell::Blend::Equation FixedPipelineState::UnpackBlendEquation(u32 packed) noexcept {
static constexpr std::array LUT = {
- Maxwell::Blend::Equation::Add, Maxwell::Blend::Equation::Subtract,
- Maxwell::Blend::Equation::ReverseSubtract, Maxwell::Blend::Equation::Min,
- Maxwell::Blend::Equation::Max};
+ Maxwell::Blend::Equation::Add_D3D, Maxwell::Blend::Equation::Subtract_D3D,
+ Maxwell::Blend::Equation::ReverseSubtract_D3D, Maxwell::Blend::Equation::Min_D3D,
+ Maxwell::Blend::Equation::Max_D3D};
return LUT[packed];
}
u32 FixedPipelineState::PackBlendFactor(Maxwell::Blend::Factor factor) noexcept {
switch (factor) {
- case Maxwell::Blend::Factor::Zero:
- case Maxwell::Blend::Factor::ZeroGL:
+ case Maxwell::Blend::Factor::Zero_D3D:
+ case Maxwell::Blend::Factor::Zero_GL:
return 0;
- case Maxwell::Blend::Factor::One:
- case Maxwell::Blend::Factor::OneGL:
+ case Maxwell::Blend::Factor::One_D3D:
+ case Maxwell::Blend::Factor::One_GL:
return 1;
- case Maxwell::Blend::Factor::SourceColor:
- case Maxwell::Blend::Factor::SourceColorGL:
+ case Maxwell::Blend::Factor::SourceColor_D3D:
+ case Maxwell::Blend::Factor::SourceColor_GL:
return 2;
- case Maxwell::Blend::Factor::OneMinusSourceColor:
- case Maxwell::Blend::Factor::OneMinusSourceColorGL:
+ case Maxwell::Blend::Factor::OneMinusSourceColor_D3D:
+ case Maxwell::Blend::Factor::OneMinusSourceColor_GL:
return 3;
- case Maxwell::Blend::Factor::SourceAlpha:
- case Maxwell::Blend::Factor::SourceAlphaGL:
+ case Maxwell::Blend::Factor::SourceAlpha_D3D:
+ case Maxwell::Blend::Factor::SourceAlpha_GL:
return 4;
- case Maxwell::Blend::Factor::OneMinusSourceAlpha:
- case Maxwell::Blend::Factor::OneMinusSourceAlphaGL:
+ case Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D:
+ case Maxwell::Blend::Factor::OneMinusSourceAlpha_GL:
return 5;
- case Maxwell::Blend::Factor::DestAlpha:
- case Maxwell::Blend::Factor::DestAlphaGL:
+ case Maxwell::Blend::Factor::DestAlpha_D3D:
+ case Maxwell::Blend::Factor::DestAlpha_GL:
return 6;
- case Maxwell::Blend::Factor::OneMinusDestAlpha:
- case Maxwell::Blend::Factor::OneMinusDestAlphaGL:
+ case Maxwell::Blend::Factor::OneMinusDestAlpha_D3D:
+ case Maxwell::Blend::Factor::OneMinusDestAlpha_GL:
return 7;
- case Maxwell::Blend::Factor::DestColor:
- case Maxwell::Blend::Factor::DestColorGL:
+ case Maxwell::Blend::Factor::DestColor_D3D:
+ case Maxwell::Blend::Factor::DestColor_GL:
return 8;
- case Maxwell::Blend::Factor::OneMinusDestColor:
- case Maxwell::Blend::Factor::OneMinusDestColorGL:
+ case Maxwell::Blend::Factor::OneMinusDestColor_D3D:
+ case Maxwell::Blend::Factor::OneMinusDestColor_GL:
return 9;
- case Maxwell::Blend::Factor::SourceAlphaSaturate:
- case Maxwell::Blend::Factor::SourceAlphaSaturateGL:
+ case Maxwell::Blend::Factor::SourceAlphaSaturate_D3D:
+ case Maxwell::Blend::Factor::SourceAlphaSaturate_GL:
return 10;
- case Maxwell::Blend::Factor::Source1Color:
- case Maxwell::Blend::Factor::Source1ColorGL:
+ case Maxwell::Blend::Factor::Source1Color_D3D:
+ case Maxwell::Blend::Factor::Source1Color_GL:
return 11;
- case Maxwell::Blend::Factor::OneMinusSource1Color:
- case Maxwell::Blend::Factor::OneMinusSource1ColorGL:
+ case Maxwell::Blend::Factor::OneMinusSource1Color_D3D:
+ case Maxwell::Blend::Factor::OneMinusSource1Color_GL:
return 12;
- case Maxwell::Blend::Factor::Source1Alpha:
- case Maxwell::Blend::Factor::Source1AlphaGL:
+ case Maxwell::Blend::Factor::Source1Alpha_D3D:
+ case Maxwell::Blend::Factor::Source1Alpha_GL:
return 13;
- case Maxwell::Blend::Factor::OneMinusSource1Alpha:
- case Maxwell::Blend::Factor::OneMinusSource1AlphaGL:
+ case Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D:
+ case Maxwell::Blend::Factor::OneMinusSource1Alpha_GL:
return 14;
- case Maxwell::Blend::Factor::ConstantColor:
- case Maxwell::Blend::Factor::ConstantColorGL:
+ case Maxwell::Blend::Factor::BlendFactor_D3D:
+ case Maxwell::Blend::Factor::ConstantColor_GL:
return 15;
- case Maxwell::Blend::Factor::OneMinusConstantColor:
- case Maxwell::Blend::Factor::OneMinusConstantColorGL:
+ case Maxwell::Blend::Factor::OneMinusBlendFactor_D3D:
+ case Maxwell::Blend::Factor::OneMinusConstantColor_GL:
return 16;
- case Maxwell::Blend::Factor::ConstantAlpha:
- case Maxwell::Blend::Factor::ConstantAlphaGL:
+ case Maxwell::Blend::Factor::BothSourceAlpha_D3D:
+ case Maxwell::Blend::Factor::ConstantAlpha_GL:
return 17;
- case Maxwell::Blend::Factor::OneMinusConstantAlpha:
- case Maxwell::Blend::Factor::OneMinusConstantAlphaGL:
+ case Maxwell::Blend::Factor::OneMinusBothSourceAlpha_D3D:
+ case Maxwell::Blend::Factor::OneMinusConstantAlpha_GL:
return 18;
}
+ UNIMPLEMENTED_MSG("Unknown blend factor {}", static_cast<u32>(factor));
return 0;
}
Maxwell::Blend::Factor FixedPipelineState::UnpackBlendFactor(u32 packed) noexcept {
static constexpr std::array LUT = {
- Maxwell::Blend::Factor::Zero,
- Maxwell::Blend::Factor::One,
- Maxwell::Blend::Factor::SourceColor,
- Maxwell::Blend::Factor::OneMinusSourceColor,
- Maxwell::Blend::Factor::SourceAlpha,
- Maxwell::Blend::Factor::OneMinusSourceAlpha,
- Maxwell::Blend::Factor::DestAlpha,
- Maxwell::Blend::Factor::OneMinusDestAlpha,
- Maxwell::Blend::Factor::DestColor,
- Maxwell::Blend::Factor::OneMinusDestColor,
- Maxwell::Blend::Factor::SourceAlphaSaturate,
- Maxwell::Blend::Factor::Source1Color,
- Maxwell::Blend::Factor::OneMinusSource1Color,
- Maxwell::Blend::Factor::Source1Alpha,
- Maxwell::Blend::Factor::OneMinusSource1Alpha,
- Maxwell::Blend::Factor::ConstantColor,
- Maxwell::Blend::Factor::OneMinusConstantColor,
- Maxwell::Blend::Factor::ConstantAlpha,
- Maxwell::Blend::Factor::OneMinusConstantAlpha,
+ Maxwell::Blend::Factor::Zero_D3D,
+ Maxwell::Blend::Factor::One_D3D,
+ Maxwell::Blend::Factor::SourceColor_D3D,
+ Maxwell::Blend::Factor::OneMinusSourceColor_D3D,
+ Maxwell::Blend::Factor::SourceAlpha_D3D,
+ Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D,
+ Maxwell::Blend::Factor::DestAlpha_D3D,
+ Maxwell::Blend::Factor::OneMinusDestAlpha_D3D,
+ Maxwell::Blend::Factor::DestColor_D3D,
+ Maxwell::Blend::Factor::OneMinusDestColor_D3D,
+ Maxwell::Blend::Factor::SourceAlphaSaturate_D3D,
+ Maxwell::Blend::Factor::Source1Color_D3D,
+ Maxwell::Blend::Factor::OneMinusSource1Color_D3D,
+ Maxwell::Blend::Factor::Source1Alpha_D3D,
+ Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D,
+ Maxwell::Blend::Factor::BlendFactor_D3D,
+ Maxwell::Blend::Factor::OneMinusBlendFactor_D3D,
+ Maxwell::Blend::Factor::BothSourceAlpha_D3D,
+ Maxwell::Blend::Factor::OneMinusBothSourceAlpha_D3D,
};
+ ASSERT(packed < LUT.size());
return LUT[packed];
}
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
index 9d60756e5..43441209c 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
@@ -21,8 +21,8 @@ struct FixedPipelineState {
static u32 PackComparisonOp(Maxwell::ComparisonOp op) noexcept;
static Maxwell::ComparisonOp UnpackComparisonOp(u32 packed) noexcept;
- static u32 PackStencilOp(Maxwell::StencilOp op) noexcept;
- static Maxwell::StencilOp UnpackStencilOp(u32 packed) noexcept;
+ static u32 PackStencilOp(Maxwell::StencilOp::Op op) noexcept;
+ static Maxwell::StencilOp::Op UnpackStencilOp(u32 packed) noexcept;
static u32 PackCullFace(Maxwell::CullFace cull) noexcept;
static Maxwell::CullFace UnpackCullFace(u32 packed) noexcept;
@@ -33,8 +33,8 @@ struct FixedPipelineState {
static u32 PackPolygonMode(Maxwell::PolygonMode mode) noexcept;
static Maxwell::PolygonMode UnpackPolygonMode(u32 packed) noexcept;
- static u32 PackLogicOp(Maxwell::LogicOperation op) noexcept;
- static Maxwell::LogicOperation UnpackLogicOp(u32 packed) noexcept;
+ static u32 PackLogicOp(Maxwell::LogicOp::Op op) noexcept;
+ static Maxwell::LogicOp::Op UnpackLogicOp(u32 packed) noexcept;
static u32 PackBlendEquation(Maxwell::Blend::Equation equation) noexcept;
static Maxwell::Blend::Equation UnpackBlendEquation(u32 packed) noexcept;
@@ -113,15 +113,15 @@ struct FixedPipelineState {
BitField<Position + 6, 3, u32> action_depth_pass;
BitField<Position + 9, 3, u32> test_func;
- Maxwell::StencilOp ActionStencilFail() const noexcept {
+ Maxwell::StencilOp::Op ActionStencilFail() const noexcept {
return UnpackStencilOp(action_stencil_fail);
}
- Maxwell::StencilOp ActionDepthFail() const noexcept {
+ Maxwell::StencilOp::Op ActionDepthFail() const noexcept {
return UnpackStencilOp(action_depth_fail);
}
- Maxwell::StencilOp ActionDepthPass() const noexcept {
+ Maxwell::StencilOp::Op ActionDepthPass() const noexcept {
return UnpackStencilOp(action_depth_pass);
}
@@ -193,7 +193,6 @@ struct FixedPipelineState {
BitField<6, 5, u32> depth_format;
BitField<11, 1, u32> y_negate;
BitField<12, 1, u32> provoking_vertex_last;
- BitField<13, 1, u32> conservative_raster_enable;
BitField<14, 1, u32> smooth_lines;
};
std::array<u8, Maxwell::NumRenderTargets> color_formats;
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
index bdb71dc53..5c156087b 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
@@ -184,7 +184,7 @@ struct FormatTuple {
{VK_FORMAT_BC3_SRGB_BLOCK}, // BC3_SRGB
{VK_FORMAT_BC7_SRGB_BLOCK}, // BC7_SRGB
{VK_FORMAT_R4G4B4A4_UNORM_PACK16, Attachable}, // A4B4G4R4_UNORM
- {VK_FORMAT_R4G4_UNORM_PACK8}, // R4G4_UNORM
+ {VK_FORMAT_R4G4_UNORM_PACK8}, // G4R4_UNORM
{VK_FORMAT_ASTC_4x4_SRGB_BLOCK}, // ASTC_2D_4X4_SRGB
{VK_FORMAT_ASTC_8x8_SRGB_BLOCK}, // ASTC_2D_8X8_SRGB
{VK_FORMAT_ASTC_8x5_SRGB_BLOCK}, // ASTC_2D_8X5_SRGB
@@ -196,6 +196,8 @@ struct FormatTuple {
{VK_FORMAT_ASTC_6x6_UNORM_BLOCK}, // ASTC_2D_6X6_UNORM
{VK_FORMAT_ASTC_6x6_SRGB_BLOCK}, // ASTC_2D_6X6_SRGB
{VK_FORMAT_ASTC_10x6_UNORM_BLOCK}, // ASTC_2D_10X6_UNORM
+ {VK_FORMAT_ASTC_10x5_UNORM_BLOCK}, // ASTC_2D_10X5_UNORM
+ {VK_FORMAT_ASTC_10x5_SRGB_BLOCK}, // ASTC_2D_10X5_SRGB
{VK_FORMAT_ASTC_10x10_UNORM_BLOCK}, // ASTC_2D_10X10_UNORM
{VK_FORMAT_ASTC_10x10_SRGB_BLOCK}, // ASTC_2D_10X10_SRGB
{VK_FORMAT_ASTC_12x12_UNORM_BLOCK}, // ASTC_2D_12X12_UNORM
@@ -321,161 +323,182 @@ VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type,
Maxwell::VertexAttribute::Size size) {
const VkFormat format{([&]() {
switch (type) {
- case Maxwell::VertexAttribute::Type::UnsignedNorm:
+ case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway:
+ ASSERT_MSG(false, "Invalid vertex attribute type!");
+ break;
+ case Maxwell::VertexAttribute::Type::UNorm:
switch (size) {
- case Maxwell::VertexAttribute::Size::Size_8:
+ case Maxwell::VertexAttribute::Size::Size_R8:
+ case Maxwell::VertexAttribute::Size::Size_A8:
return VK_FORMAT_R8_UNORM;
- case Maxwell::VertexAttribute::Size::Size_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8:
+ case Maxwell::VertexAttribute::Size::Size_G8_R8:
return VK_FORMAT_R8G8_UNORM;
- case Maxwell::VertexAttribute::Size::Size_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
return VK_FORMAT_R8G8B8_UNORM;
- case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
+ case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
return VK_FORMAT_R8G8B8A8_UNORM;
- case Maxwell::VertexAttribute::Size::Size_16:
+ case Maxwell::VertexAttribute::Size::Size_R16:
return VK_FORMAT_R16_UNORM;
- case Maxwell::VertexAttribute::Size::Size_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16:
return VK_FORMAT_R16G16_UNORM;
- case Maxwell::VertexAttribute::Size::Size_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
return VK_FORMAT_R16G16B16_UNORM;
- case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
return VK_FORMAT_R16G16B16A16_UNORM;
- case Maxwell::VertexAttribute::Size::Size_10_10_10_2:
+ case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
return VK_FORMAT_A2B10G10R10_UNORM_PACK32;
default:
break;
}
break;
- case Maxwell::VertexAttribute::Type::SignedNorm:
+ case Maxwell::VertexAttribute::Type::SNorm:
switch (size) {
- case Maxwell::VertexAttribute::Size::Size_8:
+ case Maxwell::VertexAttribute::Size::Size_R8:
+ case Maxwell::VertexAttribute::Size::Size_A8:
return VK_FORMAT_R8_SNORM;
- case Maxwell::VertexAttribute::Size::Size_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8:
+ case Maxwell::VertexAttribute::Size::Size_G8_R8:
return VK_FORMAT_R8G8_SNORM;
- case Maxwell::VertexAttribute::Size::Size_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
return VK_FORMAT_R8G8B8_SNORM;
- case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
+ case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
return VK_FORMAT_R8G8B8A8_SNORM;
- case Maxwell::VertexAttribute::Size::Size_16:
+ case Maxwell::VertexAttribute::Size::Size_R16:
return VK_FORMAT_R16_SNORM;
- case Maxwell::VertexAttribute::Size::Size_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16:
return VK_FORMAT_R16G16_SNORM;
- case Maxwell::VertexAttribute::Size::Size_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
return VK_FORMAT_R16G16B16_SNORM;
- case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
return VK_FORMAT_R16G16B16A16_SNORM;
- case Maxwell::VertexAttribute::Size::Size_10_10_10_2:
+ case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
return VK_FORMAT_A2B10G10R10_SNORM_PACK32;
default:
break;
}
break;
- case Maxwell::VertexAttribute::Type::UnsignedScaled:
+ case Maxwell::VertexAttribute::Type::UScaled:
switch (size) {
- case Maxwell::VertexAttribute::Size::Size_8:
+ case Maxwell::VertexAttribute::Size::Size_R8:
+ case Maxwell::VertexAttribute::Size::Size_A8:
return VK_FORMAT_R8_USCALED;
- case Maxwell::VertexAttribute::Size::Size_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8:
+ case Maxwell::VertexAttribute::Size::Size_G8_R8:
return VK_FORMAT_R8G8_USCALED;
- case Maxwell::VertexAttribute::Size::Size_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
return VK_FORMAT_R8G8B8_USCALED;
- case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
+ case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
return VK_FORMAT_R8G8B8A8_USCALED;
- case Maxwell::VertexAttribute::Size::Size_16:
+ case Maxwell::VertexAttribute::Size::Size_R16:
return VK_FORMAT_R16_USCALED;
- case Maxwell::VertexAttribute::Size::Size_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16:
return VK_FORMAT_R16G16_USCALED;
- case Maxwell::VertexAttribute::Size::Size_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
return VK_FORMAT_R16G16B16_USCALED;
- case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
return VK_FORMAT_R16G16B16A16_USCALED;
- case Maxwell::VertexAttribute::Size::Size_10_10_10_2:
+ case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
return VK_FORMAT_A2B10G10R10_USCALED_PACK32;
default:
break;
}
break;
- case Maxwell::VertexAttribute::Type::SignedScaled:
+ case Maxwell::VertexAttribute::Type::SScaled:
switch (size) {
- case Maxwell::VertexAttribute::Size::Size_8:
+ case Maxwell::VertexAttribute::Size::Size_R8:
+ case Maxwell::VertexAttribute::Size::Size_A8:
return VK_FORMAT_R8_SSCALED;
- case Maxwell::VertexAttribute::Size::Size_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8:
+ case Maxwell::VertexAttribute::Size::Size_G8_R8:
return VK_FORMAT_R8G8_SSCALED;
- case Maxwell::VertexAttribute::Size::Size_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
return VK_FORMAT_R8G8B8_SSCALED;
- case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
+ case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
return VK_FORMAT_R8G8B8A8_SSCALED;
- case Maxwell::VertexAttribute::Size::Size_16:
+ case Maxwell::VertexAttribute::Size::Size_R16:
return VK_FORMAT_R16_SSCALED;
- case Maxwell::VertexAttribute::Size::Size_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16:
return VK_FORMAT_R16G16_SSCALED;
- case Maxwell::VertexAttribute::Size::Size_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
return VK_FORMAT_R16G16B16_SSCALED;
- case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
return VK_FORMAT_R16G16B16A16_SSCALED;
- case Maxwell::VertexAttribute::Size::Size_10_10_10_2:
+ case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
return VK_FORMAT_A2B10G10R10_SSCALED_PACK32;
default:
break;
}
break;
- case Maxwell::VertexAttribute::Type::UnsignedInt:
+ case Maxwell::VertexAttribute::Type::UInt:
switch (size) {
- case Maxwell::VertexAttribute::Size::Size_8:
+ case Maxwell::VertexAttribute::Size::Size_R8:
+ case Maxwell::VertexAttribute::Size::Size_A8:
return VK_FORMAT_R8_UINT;
- case Maxwell::VertexAttribute::Size::Size_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8:
+ case Maxwell::VertexAttribute::Size::Size_G8_R8:
return VK_FORMAT_R8G8_UINT;
- case Maxwell::VertexAttribute::Size::Size_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
return VK_FORMAT_R8G8B8_UINT;
- case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
+ case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
return VK_FORMAT_R8G8B8A8_UINT;
- case Maxwell::VertexAttribute::Size::Size_16:
+ case Maxwell::VertexAttribute::Size::Size_R16:
return VK_FORMAT_R16_UINT;
- case Maxwell::VertexAttribute::Size::Size_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16:
return VK_FORMAT_R16G16_UINT;
- case Maxwell::VertexAttribute::Size::Size_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
return VK_FORMAT_R16G16B16_UINT;
- case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
return VK_FORMAT_R16G16B16A16_UINT;
- case Maxwell::VertexAttribute::Size::Size_32:
+ case Maxwell::VertexAttribute::Size::Size_R32:
return VK_FORMAT_R32_UINT;
- case Maxwell::VertexAttribute::Size::Size_32_32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32:
return VK_FORMAT_R32G32_UINT;
- case Maxwell::VertexAttribute::Size::Size_32_32_32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
return VK_FORMAT_R32G32B32_UINT;
- case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
return VK_FORMAT_R32G32B32A32_UINT;
- case Maxwell::VertexAttribute::Size::Size_10_10_10_2:
+ case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
return VK_FORMAT_A2B10G10R10_UINT_PACK32;
default:
break;
}
break;
- case Maxwell::VertexAttribute::Type::SignedInt:
+ case Maxwell::VertexAttribute::Type::SInt:
switch (size) {
- case Maxwell::VertexAttribute::Size::Size_8:
+ case Maxwell::VertexAttribute::Size::Size_R8:
+ case Maxwell::VertexAttribute::Size::Size_A8:
return VK_FORMAT_R8_SINT;
- case Maxwell::VertexAttribute::Size::Size_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8:
+ case Maxwell::VertexAttribute::Size::Size_G8_R8:
return VK_FORMAT_R8G8_SINT;
- case Maxwell::VertexAttribute::Size::Size_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8:
return VK_FORMAT_R8G8B8_SINT;
- case Maxwell::VertexAttribute::Size::Size_8_8_8_8:
+ case Maxwell::VertexAttribute::Size::Size_R8_G8_B8_A8:
+ case Maxwell::VertexAttribute::Size::Size_X8_B8_G8_R8:
return VK_FORMAT_R8G8B8A8_SINT;
- case Maxwell::VertexAttribute::Size::Size_16:
+ case Maxwell::VertexAttribute::Size::Size_R16:
return VK_FORMAT_R16_SINT;
- case Maxwell::VertexAttribute::Size::Size_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16:
return VK_FORMAT_R16G16_SINT;
- case Maxwell::VertexAttribute::Size::Size_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
return VK_FORMAT_R16G16B16_SINT;
- case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
return VK_FORMAT_R16G16B16A16_SINT;
- case Maxwell::VertexAttribute::Size::Size_32:
+ case Maxwell::VertexAttribute::Size::Size_R32:
return VK_FORMAT_R32_SINT;
- case Maxwell::VertexAttribute::Size::Size_32_32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32:
return VK_FORMAT_R32G32_SINT;
- case Maxwell::VertexAttribute::Size::Size_32_32_32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
return VK_FORMAT_R32G32B32_SINT;
- case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
return VK_FORMAT_R32G32B32A32_SINT;
- case Maxwell::VertexAttribute::Size::Size_10_10_10_2:
+ case Maxwell::VertexAttribute::Size::Size_A2_B10_G10_R10:
return VK_FORMAT_A2B10G10R10_SINT_PACK32;
default:
break;
@@ -483,23 +506,23 @@ VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type,
break;
case Maxwell::VertexAttribute::Type::Float:
switch (size) {
- case Maxwell::VertexAttribute::Size::Size_16:
+ case Maxwell::VertexAttribute::Size::Size_R16:
return VK_FORMAT_R16_SFLOAT;
- case Maxwell::VertexAttribute::Size::Size_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16:
return VK_FORMAT_R16G16_SFLOAT;
- case Maxwell::VertexAttribute::Size::Size_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16:
return VK_FORMAT_R16G16B16_SFLOAT;
- case Maxwell::VertexAttribute::Size::Size_16_16_16_16:
+ case Maxwell::VertexAttribute::Size::Size_R16_G16_B16_A16:
return VK_FORMAT_R16G16B16A16_SFLOAT;
- case Maxwell::VertexAttribute::Size::Size_32:
+ case Maxwell::VertexAttribute::Size::Size_R32:
return VK_FORMAT_R32_SFLOAT;
- case Maxwell::VertexAttribute::Size::Size_32_32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32:
return VK_FORMAT_R32G32_SFLOAT;
- case Maxwell::VertexAttribute::Size::Size_32_32_32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32_B32:
return VK_FORMAT_R32G32B32_SFLOAT;
- case Maxwell::VertexAttribute::Size::Size_32_32_32_32:
+ case Maxwell::VertexAttribute::Size::Size_R32_G32_B32_A32:
return VK_FORMAT_R32G32B32A32_SFLOAT;
- case Maxwell::VertexAttribute::Size::Size_11_11_10:
+ case Maxwell::VertexAttribute::Size::Size_B10_G11_R11:
return VK_FORMAT_B10G11R11_UFLOAT_PACK32;
default:
break;
@@ -519,29 +542,29 @@ VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type,
VkCompareOp ComparisonOp(Maxwell::ComparisonOp comparison) {
switch (comparison) {
- case Maxwell::ComparisonOp::Never:
- case Maxwell::ComparisonOp::NeverOld:
+ case Maxwell::ComparisonOp::Never_D3D:
+ case Maxwell::ComparisonOp::Never_GL:
return VK_COMPARE_OP_NEVER;
- case Maxwell::ComparisonOp::Less:
- case Maxwell::ComparisonOp::LessOld:
+ case Maxwell::ComparisonOp::Less_D3D:
+ case Maxwell::ComparisonOp::Less_GL:
return VK_COMPARE_OP_LESS;
- case Maxwell::ComparisonOp::Equal:
- case Maxwell::ComparisonOp::EqualOld:
+ case Maxwell::ComparisonOp::Equal_D3D:
+ case Maxwell::ComparisonOp::Equal_GL:
return VK_COMPARE_OP_EQUAL;
- case Maxwell::ComparisonOp::LessEqual:
- case Maxwell::ComparisonOp::LessEqualOld:
+ case Maxwell::ComparisonOp::LessEqual_D3D:
+ case Maxwell::ComparisonOp::LessEqual_GL:
return VK_COMPARE_OP_LESS_OR_EQUAL;
- case Maxwell::ComparisonOp::Greater:
- case Maxwell::ComparisonOp::GreaterOld:
+ case Maxwell::ComparisonOp::Greater_D3D:
+ case Maxwell::ComparisonOp::Greater_GL:
return VK_COMPARE_OP_GREATER;
- case Maxwell::ComparisonOp::NotEqual:
- case Maxwell::ComparisonOp::NotEqualOld:
+ case Maxwell::ComparisonOp::NotEqual_D3D:
+ case Maxwell::ComparisonOp::NotEqual_GL:
return VK_COMPARE_OP_NOT_EQUAL;
- case Maxwell::ComparisonOp::GreaterEqual:
- case Maxwell::ComparisonOp::GreaterEqualOld:
+ case Maxwell::ComparisonOp::GreaterEqual_D3D:
+ case Maxwell::ComparisonOp::GreaterEqual_GL:
return VK_COMPARE_OP_GREATER_OR_EQUAL;
- case Maxwell::ComparisonOp::Always:
- case Maxwell::ComparisonOp::AlwaysOld:
+ case Maxwell::ComparisonOp::Always_D3D:
+ case Maxwell::ComparisonOp::Always_GL:
return VK_COMPARE_OP_ALWAYS;
}
UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison);
@@ -561,31 +584,31 @@ VkIndexType IndexFormat(Maxwell::IndexFormat index_format) {
return {};
}
-VkStencilOp StencilOp(Maxwell::StencilOp stencil_op) {
+VkStencilOp StencilOp(Maxwell::StencilOp::Op stencil_op) {
switch (stencil_op) {
- case Maxwell::StencilOp::Keep:
- case Maxwell::StencilOp::KeepOGL:
+ case Maxwell::StencilOp::Op::Keep_D3D:
+ case Maxwell::StencilOp::Op::Keep_GL:
return VK_STENCIL_OP_KEEP;
- case Maxwell::StencilOp::Zero:
- case Maxwell::StencilOp::ZeroOGL:
+ case Maxwell::StencilOp::Op::Zero_D3D:
+ case Maxwell::StencilOp::Op::Zero_GL:
return VK_STENCIL_OP_ZERO;
- case Maxwell::StencilOp::Replace:
- case Maxwell::StencilOp::ReplaceOGL:
+ case Maxwell::StencilOp::Op::Replace_D3D:
+ case Maxwell::StencilOp::Op::Replace_GL:
return VK_STENCIL_OP_REPLACE;
- case Maxwell::StencilOp::Incr:
- case Maxwell::StencilOp::IncrOGL:
+ case Maxwell::StencilOp::Op::IncrSaturate_D3D:
+ case Maxwell::StencilOp::Op::IncrSaturate_GL:
return VK_STENCIL_OP_INCREMENT_AND_CLAMP;
- case Maxwell::StencilOp::Decr:
- case Maxwell::StencilOp::DecrOGL:
+ case Maxwell::StencilOp::Op::DecrSaturate_D3D:
+ case Maxwell::StencilOp::Op::DecrSaturate_GL:
return VK_STENCIL_OP_DECREMENT_AND_CLAMP;
- case Maxwell::StencilOp::Invert:
- case Maxwell::StencilOp::InvertOGL:
+ case Maxwell::StencilOp::Op::Invert_D3D:
+ case Maxwell::StencilOp::Op::Invert_GL:
return VK_STENCIL_OP_INVERT;
- case Maxwell::StencilOp::IncrWrap:
- case Maxwell::StencilOp::IncrWrapOGL:
+ case Maxwell::StencilOp::Op::Incr_D3D:
+ case Maxwell::StencilOp::Op::Incr_GL:
return VK_STENCIL_OP_INCREMENT_AND_WRAP;
- case Maxwell::StencilOp::DecrWrap:
- case Maxwell::StencilOp::DecrWrapOGL:
+ case Maxwell::StencilOp::Op::Decr_D3D:
+ case Maxwell::StencilOp::Op::Decr_GL:
return VK_STENCIL_OP_DECREMENT_AND_WRAP;
}
UNIMPLEMENTED_MSG("Unimplemented stencil op={}", stencil_op);
@@ -594,20 +617,20 @@ VkStencilOp StencilOp(Maxwell::StencilOp stencil_op) {
VkBlendOp BlendEquation(Maxwell::Blend::Equation equation) {
switch (equation) {
- case Maxwell::Blend::Equation::Add:
- case Maxwell::Blend::Equation::AddGL:
+ case Maxwell::Blend::Equation::Add_D3D:
+ case Maxwell::Blend::Equation::Add_GL:
return VK_BLEND_OP_ADD;
- case Maxwell::Blend::Equation::Subtract:
- case Maxwell::Blend::Equation::SubtractGL:
+ case Maxwell::Blend::Equation::Subtract_D3D:
+ case Maxwell::Blend::Equation::Subtract_GL:
return VK_BLEND_OP_SUBTRACT;
- case Maxwell::Blend::Equation::ReverseSubtract:
- case Maxwell::Blend::Equation::ReverseSubtractGL:
+ case Maxwell::Blend::Equation::ReverseSubtract_D3D:
+ case Maxwell::Blend::Equation::ReverseSubtract_GL:
return VK_BLEND_OP_REVERSE_SUBTRACT;
- case Maxwell::Blend::Equation::Min:
- case Maxwell::Blend::Equation::MinGL:
+ case Maxwell::Blend::Equation::Min_D3D:
+ case Maxwell::Blend::Equation::Min_GL:
return VK_BLEND_OP_MIN;
- case Maxwell::Blend::Equation::Max:
- case Maxwell::Blend::Equation::MaxGL:
+ case Maxwell::Blend::Equation::Max_D3D:
+ case Maxwell::Blend::Equation::Max_GL:
return VK_BLEND_OP_MAX;
}
UNIMPLEMENTED_MSG("Unimplemented blend equation={}", equation);
@@ -616,62 +639,62 @@ VkBlendOp BlendEquation(Maxwell::Blend::Equation equation) {
VkBlendFactor BlendFactor(Maxwell::Blend::Factor factor) {
switch (factor) {
- case Maxwell::Blend::Factor::Zero:
- case Maxwell::Blend::Factor::ZeroGL:
+ case Maxwell::Blend::Factor::Zero_D3D:
+ case Maxwell::Blend::Factor::Zero_GL:
return VK_BLEND_FACTOR_ZERO;
- case Maxwell::Blend::Factor::One:
- case Maxwell::Blend::Factor::OneGL:
+ case Maxwell::Blend::Factor::One_D3D:
+ case Maxwell::Blend::Factor::One_GL:
return VK_BLEND_FACTOR_ONE;
- case Maxwell::Blend::Factor::SourceColor:
- case Maxwell::Blend::Factor::SourceColorGL:
+ case Maxwell::Blend::Factor::SourceColor_D3D:
+ case Maxwell::Blend::Factor::SourceColor_GL:
return VK_BLEND_FACTOR_SRC_COLOR;
- case Maxwell::Blend::Factor::OneMinusSourceColor:
- case Maxwell::Blend::Factor::OneMinusSourceColorGL:
+ case Maxwell::Blend::Factor::OneMinusSourceColor_D3D:
+ case Maxwell::Blend::Factor::OneMinusSourceColor_GL:
return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR;
- case Maxwell::Blend::Factor::SourceAlpha:
- case Maxwell::Blend::Factor::SourceAlphaGL:
+ case Maxwell::Blend::Factor::SourceAlpha_D3D:
+ case Maxwell::Blend::Factor::SourceAlpha_GL:
return VK_BLEND_FACTOR_SRC_ALPHA;
- case Maxwell::Blend::Factor::OneMinusSourceAlpha:
- case Maxwell::Blend::Factor::OneMinusSourceAlphaGL:
+ case Maxwell::Blend::Factor::OneMinusSourceAlpha_D3D:
+ case Maxwell::Blend::Factor::OneMinusSourceAlpha_GL:
return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
- case Maxwell::Blend::Factor::DestAlpha:
- case Maxwell::Blend::Factor::DestAlphaGL:
+ case Maxwell::Blend::Factor::DestAlpha_D3D:
+ case Maxwell::Blend::Factor::DestAlpha_GL:
return VK_BLEND_FACTOR_DST_ALPHA;
- case Maxwell::Blend::Factor::OneMinusDestAlpha:
- case Maxwell::Blend::Factor::OneMinusDestAlphaGL:
+ case Maxwell::Blend::Factor::OneMinusDestAlpha_D3D:
+ case Maxwell::Blend::Factor::OneMinusDestAlpha_GL:
return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA;
- case Maxwell::Blend::Factor::DestColor:
- case Maxwell::Blend::Factor::DestColorGL:
+ case Maxwell::Blend::Factor::DestColor_D3D:
+ case Maxwell::Blend::Factor::DestColor_GL:
return VK_BLEND_FACTOR_DST_COLOR;
- case Maxwell::Blend::Factor::OneMinusDestColor:
- case Maxwell::Blend::Factor::OneMinusDestColorGL:
+ case Maxwell::Blend::Factor::OneMinusDestColor_D3D:
+ case Maxwell::Blend::Factor::OneMinusDestColor_GL:
return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR;
- case Maxwell::Blend::Factor::SourceAlphaSaturate:
- case Maxwell::Blend::Factor::SourceAlphaSaturateGL:
+ case Maxwell::Blend::Factor::SourceAlphaSaturate_D3D:
+ case Maxwell::Blend::Factor::SourceAlphaSaturate_GL:
return VK_BLEND_FACTOR_SRC_ALPHA_SATURATE;
- case Maxwell::Blend::Factor::Source1Color:
- case Maxwell::Blend::Factor::Source1ColorGL:
+ case Maxwell::Blend::Factor::Source1Color_D3D:
+ case Maxwell::Blend::Factor::Source1Color_GL:
return VK_BLEND_FACTOR_SRC1_COLOR;
- case Maxwell::Blend::Factor::OneMinusSource1Color:
- case Maxwell::Blend::Factor::OneMinusSource1ColorGL:
+ case Maxwell::Blend::Factor::OneMinusSource1Color_D3D:
+ case Maxwell::Blend::Factor::OneMinusSource1Color_GL:
return VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR;
- case Maxwell::Blend::Factor::Source1Alpha:
- case Maxwell::Blend::Factor::Source1AlphaGL:
+ case Maxwell::Blend::Factor::Source1Alpha_D3D:
+ case Maxwell::Blend::Factor::Source1Alpha_GL:
return VK_BLEND_FACTOR_SRC1_ALPHA;
- case Maxwell::Blend::Factor::OneMinusSource1Alpha:
- case Maxwell::Blend::Factor::OneMinusSource1AlphaGL:
+ case Maxwell::Blend::Factor::OneMinusSource1Alpha_D3D:
+ case Maxwell::Blend::Factor::OneMinusSource1Alpha_GL:
return VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA;
- case Maxwell::Blend::Factor::ConstantColor:
- case Maxwell::Blend::Factor::ConstantColorGL:
+ case Maxwell::Blend::Factor::BlendFactor_D3D:
+ case Maxwell::Blend::Factor::ConstantColor_GL:
return VK_BLEND_FACTOR_CONSTANT_COLOR;
- case Maxwell::Blend::Factor::OneMinusConstantColor:
- case Maxwell::Blend::Factor::OneMinusConstantColorGL:
+ case Maxwell::Blend::Factor::OneMinusBlendFactor_D3D:
+ case Maxwell::Blend::Factor::OneMinusConstantColor_GL:
return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
- case Maxwell::Blend::Factor::ConstantAlpha:
- case Maxwell::Blend::Factor::ConstantAlphaGL:
+ case Maxwell::Blend::Factor::BothSourceAlpha_D3D:
+ case Maxwell::Blend::Factor::ConstantAlpha_GL:
return VK_BLEND_FACTOR_CONSTANT_ALPHA;
- case Maxwell::Blend::Factor::OneMinusConstantAlpha:
- case Maxwell::Blend::Factor::OneMinusConstantAlphaGL:
+ case Maxwell::Blend::Factor::OneMinusBothSourceAlpha_D3D:
+ case Maxwell::Blend::Factor::OneMinusConstantAlpha_GL:
return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
}
UNIMPLEMENTED_MSG("Unimplemented blend factor={}", factor);
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.h b/src/video_core/renderer_vulkan/maxwell_to_vk.h
index 356d46292..6f65502d6 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.h
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.h
@@ -55,7 +55,7 @@ VkCompareOp ComparisonOp(Maxwell::ComparisonOp comparison);
VkIndexType IndexFormat(Maxwell::IndexFormat index_format);
-VkStencilOp StencilOp(Maxwell::StencilOp stencil_op);
+VkStencilOp StencilOp(Maxwell::StencilOp::Op stencil_op);
VkBlendOp BlendEquation(Maxwell::Blend::Equation equation);
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 7c78d0299..d8131232a 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -102,13 +102,13 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr),
surface(CreateSurface(instance, render_window)),
device(CreateDevice(instance, dld, *surface)), memory_allocator(device, false),
- state_tracker(gpu), scheduler(device, state_tracker),
+ state_tracker(), scheduler(device, state_tracker),
swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width,
render_window.GetFramebufferLayout().height, false),
blit_screen(cpu_memory, render_window, device, memory_allocator, swapchain, scheduler,
screen_info),
- rasterizer(render_window, gpu, gpu.MemoryManager(), cpu_memory, screen_info, device,
- memory_allocator, state_tracker, scheduler) {
+ rasterizer(render_window, gpu, cpu_memory, screen_info, device, memory_allocator,
+ state_tracker, scheduler) {
Report();
} catch (const vk::Exception& exception) {
LOG_ERROR(Render_Vulkan, "Vulkan initialization failed with error: {}", exception.what());
@@ -142,7 +142,7 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
const auto recreate_swapchain = [&] {
if (!has_been_recreated) {
has_been_recreated = true;
- scheduler.WaitWorker();
+ scheduler.Finish();
}
const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout();
swapchain.Create(layout.width, layout.height, is_srgb);
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index 444c29f68..89426121f 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -145,6 +145,11 @@ VkSemaphore BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
// Finish any pending renderpass
scheduler.RequestOutsideRenderPassOperationContext();
+ if (const auto swapchain_images = swapchain.GetImageCount(); swapchain_images != image_count) {
+ image_count = swapchain_images;
+ Recreate();
+ }
+
const std::size_t image_index = swapchain.GetImageIndex();
scheduler.Wait(resource_ticks[image_index]);
@@ -448,15 +453,15 @@ vk::Framebuffer BlitScreen::CreateFramebuffer(const VkImageView& image_view, VkE
void BlitScreen::CreateStaticResources() {
CreateShaders();
+ CreateSampler();
+}
+
+void BlitScreen::CreateDynamicResources() {
CreateSemaphores();
CreateDescriptorPool();
CreateDescriptorSetLayout();
CreateDescriptorSets();
CreatePipelineLayout();
- CreateSampler();
-}
-
-void BlitScreen::CreateDynamicResources() {
CreateRenderPass();
CreateFramebuffers();
CreateGraphicsPipeline();
@@ -475,11 +480,15 @@ void BlitScreen::RefreshResources(const Tegra::FramebufferConfig& framebuffer) {
fsr.reset();
}
- if (framebuffer.width == raw_width && framebuffer.height == raw_height && !raw_images.empty()) {
+ if (framebuffer.width == raw_width && framebuffer.height == raw_height &&
+ framebuffer.pixel_format == pixel_format && !raw_images.empty()) {
return;
}
+
raw_width = framebuffer.width;
raw_height = framebuffer.height;
+ pixel_format = framebuffer.pixel_format;
+
ReleaseRawImages();
CreateStagingBuffer(framebuffer);
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.h b/src/video_core/renderer_vulkan/vk_blit_screen.h
index b8c67bef0..a2b73ec54 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.h
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.h
@@ -28,6 +28,10 @@ namespace VideoCore {
class RasterizerInterface;
}
+namespace Service::android {
+enum class PixelFormat : u32;
+}
+
namespace Vulkan {
struct ScreenInfo;
@@ -109,7 +113,7 @@ private:
MemoryAllocator& memory_allocator;
Swapchain& swapchain;
Scheduler& scheduler;
- const std::size_t image_count;
+ std::size_t image_count;
const ScreenInfo& screen_info;
vk::ShaderModule vertex_shader;
@@ -156,6 +160,7 @@ private:
u32 raw_width = 0;
u32 raw_height = 0;
+ Service::android::PixelFormat pixel_format{};
std::unique_ptr<FSR> fsr;
};
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp
index f17a5ccd6..241d7573e 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp
+++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp
@@ -26,8 +26,6 @@
namespace Vulkan {
-using Tegra::Texture::SWIZZLE_TABLE;
-
namespace {
constexpr u32 ASTC_BINDING_INPUT_BUFFER = 0;
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
index 6447210e2..7906e11a8 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
@@ -126,8 +126,8 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
const u32 secondary_offset{desc.secondary_cbuf_offset + index_offset};
const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].Address() +
secondary_offset};
- const u32 lhs_raw{gpu_memory.Read<u32>(addr)};
- const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)};
+ const u32 lhs_raw{gpu_memory.Read<u32>(addr) << desc.shift_left};
+ const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr) << desc.secondary_shift_left};
return TexturePair(lhs_raw | rhs_raw, via_header_index);
}
}
diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.cpp b/src/video_core/renderer_vulkan/vk_fence_manager.cpp
index c249b34d4..0214b103a 100644
--- a/src/video_core/renderer_vulkan/vk_fence_manager.cpp
+++ b/src/video_core/renderer_vulkan/vk_fence_manager.cpp
@@ -11,11 +11,8 @@
namespace Vulkan {
-InnerFence::InnerFence(Scheduler& scheduler_, u32 payload_, bool is_stubbed_)
- : FenceBase{payload_, is_stubbed_}, scheduler{scheduler_} {}
-
-InnerFence::InnerFence(Scheduler& scheduler_, GPUVAddr address_, u32 payload_, bool is_stubbed_)
- : FenceBase{address_, payload_, is_stubbed_}, scheduler{scheduler_} {}
+InnerFence::InnerFence(Scheduler& scheduler_, bool is_stubbed_)
+ : FenceBase{is_stubbed_}, scheduler{scheduler_} {}
InnerFence::~InnerFence() = default;
@@ -48,12 +45,8 @@ FenceManager::FenceManager(VideoCore::RasterizerInterface& rasterizer_, Tegra::G
: GenericFenceManager{rasterizer_, gpu_, texture_cache_, buffer_cache_, query_cache_},
scheduler{scheduler_} {}
-Fence FenceManager::CreateFence(u32 value, bool is_stubbed) {
- return std::make_shared<InnerFence>(scheduler, value, is_stubbed);
-}
-
-Fence FenceManager::CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) {
- return std::make_shared<InnerFence>(scheduler, addr, value, is_stubbed);
+Fence FenceManager::CreateFence(bool is_stubbed) {
+ return std::make_shared<InnerFence>(scheduler, is_stubbed);
}
void FenceManager::QueueFence(Fence& fence) {
diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.h b/src/video_core/renderer_vulkan/vk_fence_manager.h
index 7c0bbd80a..7fe2afcd9 100644
--- a/src/video_core/renderer_vulkan/vk_fence_manager.h
+++ b/src/video_core/renderer_vulkan/vk_fence_manager.h
@@ -25,8 +25,7 @@ class Scheduler;
class InnerFence : public VideoCommon::FenceBase {
public:
- explicit InnerFence(Scheduler& scheduler_, u32 payload_, bool is_stubbed_);
- explicit InnerFence(Scheduler& scheduler_, GPUVAddr address_, u32 payload_, bool is_stubbed_);
+ explicit InnerFence(Scheduler& scheduler_, bool is_stubbed_);
~InnerFence();
void Queue();
@@ -50,8 +49,7 @@ public:
QueryCache& query_cache, const Device& device, Scheduler& scheduler);
protected:
- Fence CreateFence(u32 value, bool is_stubbed) override;
- Fence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) override;
+ Fence CreateFence(bool is_stubbed) override;
void QueueFence(Fence& fence) override;
bool IsFenceSignaled(Fence& fence) const override;
void WaitFence(Fence& fence) override;
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index 7eb623a7c..b4372a839 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -216,15 +216,14 @@ ConfigureFuncPtr ConfigureFunc(const std::array<vk::ShaderModule, NUM_STAGES>& m
} // Anonymous namespace
GraphicsPipeline::GraphicsPipeline(
- Tegra::Engines::Maxwell3D& maxwell3d_, Tegra::MemoryManager& gpu_memory_, Scheduler& scheduler_,
- BufferCache& buffer_cache_, TextureCache& texture_cache_,
+ Scheduler& scheduler_, BufferCache& buffer_cache_, TextureCache& texture_cache_,
VideoCore::ShaderNotify* shader_notify, const Device& device_, DescriptorPool& descriptor_pool,
UpdateDescriptorQueue& update_descriptor_queue_, Common::ThreadWorker* worker_thread,
PipelineStatistics* pipeline_statistics, RenderPassCache& render_pass_cache,
const GraphicsPipelineCacheKey& key_, std::array<vk::ShaderModule, NUM_STAGES> stages,
const std::array<const Shader::Info*, NUM_STAGES>& infos)
- : key{key_}, maxwell3d{maxwell3d_}, gpu_memory{gpu_memory_}, device{device_},
- texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, scheduler{scheduler_},
+ : key{key_}, device{device_}, texture_cache{texture_cache_},
+ buffer_cache{buffer_cache_}, scheduler{scheduler_},
update_descriptor_queue{update_descriptor_queue_}, spv_modules{std::move(stages)} {
if (shader_notify) {
shader_notify->MarkShaderBuilding();
@@ -289,8 +288,8 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
buffer_cache.SetUniformBuffersState(enabled_uniform_buffer_masks, &uniform_buffer_sizes);
- const auto& regs{maxwell3d.regs};
- const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex};
+ const auto& regs{maxwell3d->regs};
+ const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding};
const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE {
const Shader::Info& info{stage_infos[stage]};
buffer_cache.UnbindGraphicsStorageBuffers(stage);
@@ -303,7 +302,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
++ssbo_index;
}
}
- const auto& cbufs{maxwell3d.state.shader_stages[stage].const_buffers};
+ const auto& cbufs{maxwell3d->state.shader_stages[stage].const_buffers};
const auto read_handle{[&](const auto& desc, u32 index) {
ASSERT(cbufs[desc.cbuf_index].enabled);
const u32 index_offset{index << desc.size_shift};
@@ -316,13 +315,14 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
const u32 second_offset{desc.secondary_cbuf_offset + index_offset};
const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address +
second_offset};
- const u32 lhs_raw{gpu_memory.Read<u32>(addr)};
- const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)};
+ const u32 lhs_raw{gpu_memory->Read<u32>(addr) << desc.shift_left};
+ const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)
+ << desc.secondary_shift_left};
const u32 raw{lhs_raw | rhs_raw};
return TexturePair(raw, via_header_index);
}
}
- return TexturePair(gpu_memory.Read<u32>(addr), via_header_index);
+ return TexturePair(gpu_memory->Read<u32>(addr), via_header_index);
}};
const auto add_image{[&](const auto& desc, bool blacklist) LAMBDA_FORCEINLINE {
for (u32 index = 0; index < desc.count; ++index) {
@@ -680,15 +680,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
.lineStippleFactor = 0,
.lineStipplePattern = 0,
};
- VkPipelineRasterizationConservativeStateCreateInfoEXT conservative_raster{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT,
- .pNext = nullptr,
- .flags = 0,
- .conservativeRasterizationMode = key.state.conservative_raster_enable != 0
- ? VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT
- : VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT,
- .extraPrimitiveOverestimationSize = 0.0f,
- };
VkPipelineRasterizationProvokingVertexStateCreateInfoEXT provoking_vertex{
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT,
.pNext = nullptr,
@@ -699,9 +690,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
if (IsLine(input_assembly_topology) && device.IsExtLineRasterizationSupported()) {
line_state.pNext = std::exchange(rasterization_ci.pNext, &line_state);
}
- if (device.IsExtConservativeRasterizationSupported()) {
- conservative_raster.pNext = std::exchange(rasterization_ci.pNext, &conservative_raster);
- }
if (device.IsExtProvokingVertexSupported()) {
provoking_vertex.pNext = std::exchange(rasterization_ci.pNext, &provoking_vertex);
}
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h
index 8842f62d7..6bf577d25 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h
@@ -70,15 +70,16 @@ class GraphicsPipeline {
static constexpr size_t NUM_STAGES = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage;
public:
- explicit GraphicsPipeline(
- Tegra::Engines::Maxwell3D& maxwell3d, Tegra::MemoryManager& gpu_memory,
- Scheduler& scheduler, BufferCache& buffer_cache, TextureCache& texture_cache,
- VideoCore::ShaderNotify* shader_notify, const Device& device,
- DescriptorPool& descriptor_pool, UpdateDescriptorQueue& update_descriptor_queue,
- Common::ThreadWorker* worker_thread, PipelineStatistics* pipeline_statistics,
- RenderPassCache& render_pass_cache, const GraphicsPipelineCacheKey& key,
- std::array<vk::ShaderModule, NUM_STAGES> stages,
- const std::array<const Shader::Info*, NUM_STAGES>& infos);
+ explicit GraphicsPipeline(Scheduler& scheduler, BufferCache& buffer_cache,
+ TextureCache& texture_cache, VideoCore::ShaderNotify* shader_notify,
+ const Device& device, DescriptorPool& descriptor_pool,
+ UpdateDescriptorQueue& update_descriptor_queue,
+ Common::ThreadWorker* worker_thread,
+ PipelineStatistics* pipeline_statistics,
+ RenderPassCache& render_pass_cache,
+ const GraphicsPipelineCacheKey& key,
+ std::array<vk::ShaderModule, NUM_STAGES> stages,
+ const std::array<const Shader::Info*, NUM_STAGES>& infos);
GraphicsPipeline& operator=(GraphicsPipeline&&) noexcept = delete;
GraphicsPipeline(GraphicsPipeline&&) noexcept = delete;
@@ -110,6 +111,11 @@ public:
return [](GraphicsPipeline* pl, bool is_indexed) { pl->ConfigureImpl<Spec>(is_indexed); };
}
+ void SetEngine(Tegra::Engines::Maxwell3D* maxwell3d_, Tegra::MemoryManager* gpu_memory_) {
+ maxwell3d = maxwell3d_;
+ gpu_memory = gpu_memory_;
+ }
+
private:
template <typename Spec>
void ConfigureImpl(bool is_indexed);
@@ -122,8 +128,8 @@ private:
void Validate();
const GraphicsPipelineCacheKey key;
- Tegra::Engines::Maxwell3D& maxwell3d;
- Tegra::MemoryManager& gpu_memory;
+ Tegra::Engines::Maxwell3D* maxwell3d;
+ Tegra::MemoryManager* gpu_memory;
const Device& device;
TextureCache& texture_cache;
BufferCache& buffer_cache;
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 9708dc45e..13d5a1f67 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -62,29 +62,29 @@ auto MakeSpan(Container& container) {
Shader::CompareFunction MaxwellToCompareFunction(Maxwell::ComparisonOp comparison) {
switch (comparison) {
- case Maxwell::ComparisonOp::Never:
- case Maxwell::ComparisonOp::NeverOld:
+ case Maxwell::ComparisonOp::Never_D3D:
+ case Maxwell::ComparisonOp::Never_GL:
return Shader::CompareFunction::Never;
- case Maxwell::ComparisonOp::Less:
- case Maxwell::ComparisonOp::LessOld:
+ case Maxwell::ComparisonOp::Less_D3D:
+ case Maxwell::ComparisonOp::Less_GL:
return Shader::CompareFunction::Less;
- case Maxwell::ComparisonOp::Equal:
- case Maxwell::ComparisonOp::EqualOld:
+ case Maxwell::ComparisonOp::Equal_D3D:
+ case Maxwell::ComparisonOp::Equal_GL:
return Shader::CompareFunction::Equal;
- case Maxwell::ComparisonOp::LessEqual:
- case Maxwell::ComparisonOp::LessEqualOld:
+ case Maxwell::ComparisonOp::LessEqual_D3D:
+ case Maxwell::ComparisonOp::LessEqual_GL:
return Shader::CompareFunction::LessThanEqual;
- case Maxwell::ComparisonOp::Greater:
- case Maxwell::ComparisonOp::GreaterOld:
+ case Maxwell::ComparisonOp::Greater_D3D:
+ case Maxwell::ComparisonOp::Greater_GL:
return Shader::CompareFunction::Greater;
- case Maxwell::ComparisonOp::NotEqual:
- case Maxwell::ComparisonOp::NotEqualOld:
+ case Maxwell::ComparisonOp::NotEqual_D3D:
+ case Maxwell::ComparisonOp::NotEqual_GL:
return Shader::CompareFunction::NotEqual;
- case Maxwell::ComparisonOp::GreaterEqual:
- case Maxwell::ComparisonOp::GreaterEqualOld:
+ case Maxwell::ComparisonOp::GreaterEqual_D3D:
+ case Maxwell::ComparisonOp::GreaterEqual_GL:
return Shader::CompareFunction::GreaterThanEqual;
- case Maxwell::ComparisonOp::Always:
- case Maxwell::ComparisonOp::AlwaysOld:
+ case Maxwell::ComparisonOp::Always_D3D:
+ case Maxwell::ComparisonOp::Always_GL:
return Shader::CompareFunction::Always;
}
UNIMPLEMENTED_MSG("Unimplemented comparison op={}", comparison);
@@ -96,15 +96,18 @@ Shader::AttributeType CastAttributeType(const FixedPipelineState::VertexAttribut
return Shader::AttributeType::Disabled;
}
switch (attr.Type()) {
- case Maxwell::VertexAttribute::Type::SignedNorm:
- case Maxwell::VertexAttribute::Type::UnsignedNorm:
- case Maxwell::VertexAttribute::Type::UnsignedScaled:
- case Maxwell::VertexAttribute::Type::SignedScaled:
+ case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway:
+ ASSERT_MSG(false, "Invalid vertex attribute type!");
+ return Shader::AttributeType::Disabled;
+ case Maxwell::VertexAttribute::Type::SNorm:
+ case Maxwell::VertexAttribute::Type::UNorm:
+ case Maxwell::VertexAttribute::Type::UScaled:
+ case Maxwell::VertexAttribute::Type::SScaled:
case Maxwell::VertexAttribute::Type::Float:
return Shader::AttributeType::Float;
- case Maxwell::VertexAttribute::Type::SignedInt:
+ case Maxwell::VertexAttribute::Type::SInt:
return Shader::AttributeType::SignedInt;
- case Maxwell::VertexAttribute::Type::UnsignedInt:
+ case Maxwell::VertexAttribute::Type::UInt:
return Shader::AttributeType::UnsignedInt;
}
return Shader::AttributeType::Float;
@@ -131,6 +134,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
Shader::RuntimeInfo info;
if (previous_program) {
info.previous_stage_stores = previous_program->info.stores;
+ info.previous_stage_legacy_stores_mapping = previous_program->info.legacy_stores_mapping;
if (previous_program->is_geometry_passthrough) {
info.previous_stage_stores.mask |= previous_program->info.passthrough.mask;
}
@@ -162,16 +166,14 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
}
break;
case Shader::Stage::TessellationEval:
- // We have to flip tessellation clockwise for some reason...
- info.tess_clockwise = key.state.tessellation_clockwise == 0;
info.tess_primitive = [&key] {
const u32 raw{key.state.tessellation_primitive.Value()};
- switch (static_cast<Maxwell::TessellationPrimitive>(raw)) {
- case Maxwell::TessellationPrimitive::Isolines:
+ switch (static_cast<Maxwell::Tessellation::DomainType>(raw)) {
+ case Maxwell::Tessellation::DomainType::Isolines:
return Shader::TessPrimitive::Isolines;
- case Maxwell::TessellationPrimitive::Triangles:
+ case Maxwell::Tessellation::DomainType::Triangles:
return Shader::TessPrimitive::Triangles;
- case Maxwell::TessellationPrimitive::Quads:
+ case Maxwell::Tessellation::DomainType::Quads:
return Shader::TessPrimitive::Quads;
}
ASSERT(false);
@@ -179,12 +181,12 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
}();
info.tess_spacing = [&] {
const u32 raw{key.state.tessellation_spacing};
- switch (static_cast<Maxwell::TessellationSpacing>(raw)) {
- case Maxwell::TessellationSpacing::Equal:
+ switch (static_cast<Maxwell::Tessellation::Spacing>(raw)) {
+ case Maxwell::Tessellation::Spacing::Integer:
return Shader::TessSpacing::Equal;
- case Maxwell::TessellationSpacing::FractionalOdd:
+ case Maxwell::Tessellation::Spacing::FractionalOdd:
return Shader::TessSpacing::FractionalOdd;
- case Maxwell::TessellationSpacing::FractionalEven:
+ case Maxwell::Tessellation::Spacing::FractionalEven:
return Shader::TessSpacing::FractionalEven;
}
ASSERT(false);
@@ -259,20 +261,18 @@ bool GraphicsPipelineCacheKey::operator==(const GraphicsPipelineCacheKey& rhs) c
return std::memcmp(&rhs, this, Size()) == 0;
}
-PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::Engines::Maxwell3D& maxwell3d_,
- Tegra::Engines::KeplerCompute& kepler_compute_,
- Tegra::MemoryManager& gpu_memory_, const Device& device_,
+PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device_,
Scheduler& scheduler_, DescriptorPool& descriptor_pool_,
UpdateDescriptorQueue& update_descriptor_queue_,
RenderPassCache& render_pass_cache_, BufferCache& buffer_cache_,
TextureCache& texture_cache_, VideoCore::ShaderNotify& shader_notify_)
- : VideoCommon::ShaderCache{rasterizer_, gpu_memory_, maxwell3d_, kepler_compute_},
- device{device_}, scheduler{scheduler_}, descriptor_pool{descriptor_pool_},
- update_descriptor_queue{update_descriptor_queue_}, render_pass_cache{render_pass_cache_},
- buffer_cache{buffer_cache_}, texture_cache{texture_cache_}, shader_notify{shader_notify_},
+ : VideoCommon::ShaderCache{rasterizer_}, device{device_}, scheduler{scheduler_},
+ descriptor_pool{descriptor_pool_}, update_descriptor_queue{update_descriptor_queue_},
+ render_pass_cache{render_pass_cache_}, buffer_cache{buffer_cache_},
+ texture_cache{texture_cache_}, shader_notify{shader_notify_},
use_asynchronous_shaders{Settings::values.use_asynchronous_shaders.GetValue()},
- workers(std::max(std::thread::hardware_concurrency(), 2U) - 1, "yuzu:PipelineBuilder"),
- serialization_thread(1, "yuzu:PipelineSerialization") {
+ workers(std::max(std::thread::hardware_concurrency(), 2U) - 1, "VkPipelineBuilder"),
+ serialization_thread(1, "VkPipelineSerialization") {
const auto& float_control{device.FloatControlProperties()};
const VkDriverIdKHR driver_id{device.GetDriverID()};
profile = Shader::Profile{
@@ -337,7 +337,7 @@ GraphicsPipeline* PipelineCache::CurrentGraphicsPipeline() {
current_pipeline = nullptr;
return nullptr;
}
- graphics_key.state.Refresh(maxwell3d, device.IsExtExtendedDynamicStateSupported(),
+ graphics_key.state.Refresh(*maxwell3d, device.IsExtExtendedDynamicStateSupported(),
device.IsExtVertexInputDynamicStateSupported());
if (current_pipeline) {
@@ -357,7 +357,7 @@ ComputePipeline* PipelineCache::CurrentComputePipeline() {
if (!shader) {
return nullptr;
}
- const auto& qmd{kepler_compute.launch_description};
+ const auto& qmd{kepler_compute->launch_description};
const ComputePipelineCacheKey key{
.unique_hash = shader->unique_hash,
.shared_memory_size = qmd.shared_alloc,
@@ -486,13 +486,13 @@ GraphicsPipeline* PipelineCache::BuiltPipeline(GraphicsPipeline* pipeline) const
}
// If something is using depth, we can assume that games are not rendering anything which
// will be used one time.
- if (maxwell3d.regs.zeta_enable) {
+ if (maxwell3d->regs.zeta_enable) {
return nullptr;
}
// If games are using a small index count, we can assume these are full screen quads.
// Usually these shaders are only used once for building textures so we can assume they
// can't be built async
- if (maxwell3d.regs.index_array.count <= 6 || maxwell3d.regs.vertex_buffer.count <= 6) {
+ if (maxwell3d->regs.index_buffer.count <= 6 || maxwell3d->regs.vertex_buffer.count <= 6) {
return pipeline;
}
return nullptr;
@@ -557,10 +557,10 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
previous_stage = &program;
}
Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr};
- return std::make_unique<GraphicsPipeline>(
- maxwell3d, gpu_memory, scheduler, buffer_cache, texture_cache, &shader_notify, device,
- descriptor_pool, update_descriptor_queue, thread_worker, statistics, render_pass_cache, key,
- std::move(modules), infos);
+ return std::make_unique<GraphicsPipeline>(scheduler, buffer_cache, texture_cache,
+ &shader_notify, device, descriptor_pool,
+ update_descriptor_queue, thread_worker, statistics,
+ render_pass_cache, key, std::move(modules), infos);
} catch (const Shader::Exception& exception) {
LOG_ERROR(Render_Vulkan, "{}", exception.what());
@@ -592,9 +592,9 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
const ComputePipelineCacheKey& key, const ShaderInfo* shader) {
- const GPUVAddr program_base{kepler_compute.regs.code_loc.Address()};
- const auto& qmd{kepler_compute.launch_description};
- ComputeEnvironment env{kepler_compute, gpu_memory, program_base, qmd.program_start};
+ const GPUVAddr program_base{kepler_compute->regs.code_loc.Address()};
+ const auto& qmd{kepler_compute->launch_description};
+ ComputeEnvironment env{*kepler_compute, *gpu_memory, program_base, qmd.program_start};
env.SetCachedSize(shader->size_bytes);
main_pools.ReleaseContents();
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
index 127957dbf..61f9e9366 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
@@ -100,10 +100,8 @@ struct ShaderPools {
class PipelineCache : public VideoCommon::ShaderCache {
public:
- explicit PipelineCache(RasterizerVulkan& rasterizer, Tegra::Engines::Maxwell3D& maxwell3d,
- Tegra::Engines::KeplerCompute& kepler_compute,
- Tegra::MemoryManager& gpu_memory, const Device& device,
- Scheduler& scheduler, DescriptorPool& descriptor_pool,
+ explicit PipelineCache(RasterizerVulkan& rasterizer, const Device& device, Scheduler& scheduler,
+ DescriptorPool& descriptor_pool,
UpdateDescriptorQueue& update_descriptor_queue,
RenderPassCache& render_pass_cache, BufferCache& buffer_cache,
TextureCache& texture_cache, VideoCore::ShaderNotify& shader_notify_);
diff --git a/src/video_core/renderer_vulkan/vk_query_cache.cpp b/src/video_core/renderer_vulkan/vk_query_cache.cpp
index 2b859c6b8..4b15c0f85 100644
--- a/src/video_core/renderer_vulkan/vk_query_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_query_cache.cpp
@@ -59,16 +59,16 @@ void QueryPool::Reserve(std::pair<VkQueryPool, u32> query) {
std::find_if(pools.begin(), pools.end(), [query_pool = query.first](vk::QueryPool& pool) {
return query_pool == *pool;
});
- ASSERT(it != std::end(pools));
- const std::ptrdiff_t pool_index = std::distance(std::begin(pools), it);
- usage[pool_index * GROW_STEP + static_cast<std::ptrdiff_t>(query.second)] = false;
+ if (it != std::end(pools)) {
+ const std::ptrdiff_t pool_index = std::distance(std::begin(pools), it);
+ usage[pool_index * GROW_STEP + static_cast<std::ptrdiff_t>(query.second)] = false;
+ }
}
-QueryCache::QueryCache(VideoCore::RasterizerInterface& rasterizer_,
- Tegra::Engines::Maxwell3D& maxwell3d_, Tegra::MemoryManager& gpu_memory_,
- const Device& device_, Scheduler& scheduler_)
- : QueryCacheBase{rasterizer_, maxwell3d_, gpu_memory_}, device{device_}, scheduler{scheduler_},
+QueryCache::QueryCache(VideoCore::RasterizerInterface& rasterizer_, const Device& device_,
+ Scheduler& scheduler_)
+ : QueryCacheBase{rasterizer_}, device{device_}, scheduler{scheduler_},
query_pools{
QueryPool{device_, scheduler_, QueryType::SamplesPassed},
} {}
diff --git a/src/video_core/renderer_vulkan/vk_query_cache.h b/src/video_core/renderer_vulkan/vk_query_cache.h
index b0d86c4f8..26762ee09 100644
--- a/src/video_core/renderer_vulkan/vk_query_cache.h
+++ b/src/video_core/renderer_vulkan/vk_query_cache.h
@@ -52,9 +52,8 @@ private:
class QueryCache final
: public VideoCommon::QueryCacheBase<QueryCache, CachedQuery, CounterStream, HostCounter> {
public:
- explicit QueryCache(VideoCore::RasterizerInterface& rasterizer_,
- Tegra::Engines::Maxwell3D& maxwell3d_, Tegra::MemoryManager& gpu_memory_,
- const Device& device_, Scheduler& scheduler_);
+ explicit QueryCache(VideoCore::RasterizerInterface& rasterizer_, const Device& device_,
+ Scheduler& scheduler_);
~QueryCache();
std::pair<VkQueryPool, u32> AllocateQuery(VideoCore::QueryType type);
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index bf9f825f4..5af3c930b 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -11,6 +11,7 @@
#include "common/microprofile.h"
#include "common/scope_exit.h"
#include "common/settings.h"
+#include "video_core/control/channel_state.h"
#include "video_core/engines/kepler_compute.h"
#include "video_core/engines/maxwell_3d.h"
#include "video_core/renderer_vulkan/blit_image.h"
@@ -69,7 +70,7 @@ VkViewport GetViewportState(const Device& device, const Maxwell& regs, size_t in
const float width = conv(src.scale_x * 2.0f);
float y = conv(src.translate_y - src.scale_y);
float height = conv(src.scale_y * 2.0f);
- bool y_negate = regs.screen_y_control.y_negate;
+ bool y_negate = regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft;
if (!device.IsNvViewportSwizzleSupported()) {
y_negate = y_negate != (src.swizzle.y == Maxwell::ViewportSwizzle::NegativeY);
@@ -126,14 +127,13 @@ VkRect2D GetScissorState(const Maxwell& regs, size_t index, u32 up_scale = 1, u3
return scissor;
}
-DrawParams MakeDrawParams(const Maxwell& regs, u32 num_instances, bool is_instanced,
- bool is_indexed) {
+DrawParams MakeDrawParams(const Maxwell& regs, u32 num_instances, bool is_indexed) {
DrawParams params{
- .base_instance = regs.vb_base_instance,
- .num_instances = is_instanced ? num_instances : 1,
- .base_vertex = is_indexed ? regs.vb_element_base : regs.vertex_buffer.first,
- .num_vertices = is_indexed ? regs.index_array.count : regs.vertex_buffer.count,
- .first_index = is_indexed ? regs.index_array.first : 0,
+ .base_instance = regs.global_base_instance_index,
+ .num_instances = num_instances,
+ .base_vertex = is_indexed ? regs.global_base_vertex_index : regs.vertex_buffer.first,
+ .num_vertices = is_indexed ? regs.index_buffer.count : regs.vertex_buffer.count,
+ .first_index = is_indexed ? regs.index_buffer.first : 0,
.is_indexed = is_indexed,
};
if (regs.draw.topology == Maxwell::PrimitiveTopology::Quads) {
@@ -148,31 +148,25 @@ DrawParams MakeDrawParams(const Maxwell& regs, u32 num_instances, bool is_instan
} // Anonymous namespace
RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
- Tegra::MemoryManager& gpu_memory_,
Core::Memory::Memory& cpu_memory_, ScreenInfo& screen_info_,
const Device& device_, MemoryAllocator& memory_allocator_,
StateTracker& state_tracker_, Scheduler& scheduler_)
- : RasterizerAccelerated{cpu_memory_}, gpu{gpu_},
- gpu_memory{gpu_memory_}, maxwell3d{gpu.Maxwell3D()}, kepler_compute{gpu.KeplerCompute()},
- screen_info{screen_info_}, device{device_}, memory_allocator{memory_allocator_},
- state_tracker{state_tracker_}, scheduler{scheduler_},
+ : RasterizerAccelerated{cpu_memory_}, gpu{gpu_}, screen_info{screen_info_}, device{device_},
+ memory_allocator{memory_allocator_}, state_tracker{state_tracker_}, scheduler{scheduler_},
staging_pool(device, memory_allocator, scheduler), descriptor_pool(device, scheduler),
update_descriptor_queue(device, scheduler),
blit_image(device, scheduler, state_tracker, descriptor_pool),
- astc_decoder_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue,
- memory_allocator),
render_pass_cache(device), texture_cache_runtime{device, scheduler,
memory_allocator, staging_pool,
- blit_image, astc_decoder_pass,
- render_pass_cache},
- texture_cache(texture_cache_runtime, *this, maxwell3d, kepler_compute, gpu_memory),
+ blit_image, render_pass_cache,
+ descriptor_pool, update_descriptor_queue},
+ texture_cache(texture_cache_runtime, *this),
buffer_cache_runtime(device, memory_allocator, scheduler, staging_pool,
update_descriptor_queue, descriptor_pool),
- buffer_cache(*this, maxwell3d, kepler_compute, gpu_memory, cpu_memory_, buffer_cache_runtime),
- pipeline_cache(*this, maxwell3d, kepler_compute, gpu_memory, device, scheduler,
- descriptor_pool, update_descriptor_queue, render_pass_cache, buffer_cache,
- texture_cache, gpu.ShaderNotify()),
- query_cache{*this, maxwell3d, gpu_memory, device, scheduler}, accelerate_dma{buffer_cache},
+ buffer_cache(*this, cpu_memory_, buffer_cache_runtime),
+ pipeline_cache(*this, device, scheduler, descriptor_pool, update_descriptor_queue,
+ render_pass_cache, buffer_cache, texture_cache, gpu.ShaderNotify()),
+ query_cache{*this, device, scheduler}, accelerate_dma{buffer_cache},
fence_manager(*this, gpu, texture_cache, buffer_cache, query_cache, device, scheduler),
wfi_event(device.GetLogical().CreateEvent()) {
scheduler.SetQueryCache(query_cache);
@@ -180,7 +174,7 @@ RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra
RasterizerVulkan::~RasterizerVulkan() = default;
-void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {
+void RasterizerVulkan::Draw(bool is_indexed, u32 instance_count) {
MICROPROFILE_SCOPE(Vulkan_Drawing);
SCOPE_EXIT({ gpu.TickWork(); });
@@ -193,15 +187,19 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {
return;
}
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ // update engine as channel may be different.
+ pipeline->SetEngine(maxwell3d, gpu_memory);
pipeline->Configure(is_indexed);
+ BindInlineIndexBuffer();
+
BeginTransformFeedback();
UpdateDynamicStates();
- const auto& regs{maxwell3d.regs};
- const u32 num_instances{maxwell3d.mme_draw.instance_count};
- const DrawParams draw_params{MakeDrawParams(regs, num_instances, is_instanced, is_indexed)};
+ const auto& regs{maxwell3d->regs};
+ const u32 num_instances{instance_count};
+ const DrawParams draw_params{MakeDrawParams(regs, num_instances, is_indexed)};
scheduler.Record([draw_params](vk::CommandBuffer cmdbuf) {
if (draw_params.is_indexed) {
cmdbuf.DrawIndexed(draw_params.num_vertices, draw_params.num_instances,
@@ -218,18 +216,18 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {
void RasterizerVulkan::Clear() {
MICROPROFILE_SCOPE(Vulkan_Clearing);
- if (!maxwell3d.ShouldExecute()) {
+ if (!maxwell3d->ShouldExecute()) {
return;
}
FlushWork();
query_cache.UpdateCounters();
- auto& regs = maxwell3d.regs;
- const bool use_color = regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
- regs.clear_buffers.A;
- const bool use_depth = regs.clear_buffers.Z;
- const bool use_stencil = regs.clear_buffers.S;
+ auto& regs = maxwell3d->regs;
+ const bool use_color = regs.clear_surface.R || regs.clear_surface.G || regs.clear_surface.B ||
+ regs.clear_surface.A;
+ const bool use_depth = regs.clear_surface.Z;
+ const bool use_stencil = regs.clear_surface.S;
if (!use_color && !use_depth && !use_stencil) {
return;
}
@@ -248,9 +246,16 @@ void RasterizerVulkan::Clear() {
}
UpdateViewportsState(regs);
+ VkRect2D default_scissor;
+ default_scissor.offset.x = 0;
+ default_scissor.offset.y = 0;
+ default_scissor.extent.width = std::numeric_limits<s32>::max();
+ default_scissor.extent.height = std::numeric_limits<s32>::max();
+
VkClearRect clear_rect{
- .rect = GetScissorState(regs, 0, up_scale, down_shift),
- .baseArrayLayer = regs.clear_buffers.layer,
+ .rect = regs.clear_control.use_scissor ? GetScissorState(regs, 0, up_scale, down_shift)
+ : default_scissor,
+ .baseArrayLayer = regs.clear_surface.layer,
.layerCount = 1,
};
if (clear_rect.rect.extent.width == 0 || clear_rect.rect.extent.height == 0) {
@@ -261,7 +266,7 @@ void RasterizerVulkan::Clear() {
.height = std::min(clear_rect.rect.extent.height, render_area.height),
};
- const u32 color_attachment = regs.clear_buffers.RT;
+ const u32 color_attachment = regs.clear_surface.RT;
if (use_color && framebuffer->HasAspectColorBit(color_attachment)) {
VkClearValue clear_value;
bool is_integer = false;
@@ -283,7 +288,8 @@ void RasterizerVulkan::Clear() {
break;
}
if (!is_integer) {
- std::memcpy(clear_value.color.float32, regs.clear_color, sizeof(regs.clear_color));
+ std::memcpy(clear_value.color.float32, regs.clear_color.data(),
+ regs.clear_color.size() * sizeof(f32));
} else if (!is_signed) {
for (size_t i = 0; i < 4; i++) {
clear_value.color.uint32[i] = static_cast<u32>(
@@ -297,14 +303,19 @@ void RasterizerVulkan::Clear() {
}
}
- scheduler.Record([color_attachment, clear_value, clear_rect](vk::CommandBuffer cmdbuf) {
- const VkClearAttachment attachment{
- .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
- .colorAttachment = color_attachment,
- .clearValue = clear_value,
- };
- cmdbuf.ClearAttachments(attachment, clear_rect);
- });
+ if (regs.clear_surface.R && regs.clear_surface.G && regs.clear_surface.B &&
+ regs.clear_surface.A) {
+ scheduler.Record([color_attachment, clear_value, clear_rect](vk::CommandBuffer cmdbuf) {
+ const VkClearAttachment attachment{
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .colorAttachment = color_attachment,
+ .clearValue = clear_value,
+ };
+ cmdbuf.ClearAttachments(attachment, clear_rect);
+ });
+ } else {
+ UNIMPLEMENTED_MSG("Unimplemented Clear only the specified channel");
+ }
}
if (!use_depth && !use_stencil) {
@@ -339,9 +350,9 @@ void RasterizerVulkan::DispatchCompute() {
return;
}
std::scoped_lock lock{texture_cache.mutex, buffer_cache.mutex};
- pipeline->Configure(kepler_compute, gpu_memory, scheduler, buffer_cache, texture_cache);
+ pipeline->Configure(*kepler_compute, *gpu_memory, scheduler, buffer_cache, texture_cache);
- const auto& qmd{kepler_compute.launch_description};
+ const auto& qmd{kepler_compute->launch_description};
const std::array<u32, 3> dim{qmd.grid_dim_x, qmd.grid_dim_y, qmd.grid_dim_z};
scheduler.RequestOutsideRenderPassOperationContext();
scheduler.Record([dim](vk::CommandBuffer cmdbuf) { cmdbuf.Dispatch(dim[0], dim[1], dim[2]); });
@@ -422,7 +433,7 @@ void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) {
}
}
-void RasterizerVulkan::SyncGuestHost() {
+void RasterizerVulkan::InvalidateGPUCache() {
pipeline_cache.SyncGuestHost();
{
std::scoped_lock lock{buffer_cache.mutex};
@@ -442,40 +453,30 @@ void RasterizerVulkan::UnmapMemory(VAddr addr, u64 size) {
pipeline_cache.OnCPUWrite(addr, size);
}
-void RasterizerVulkan::ModifyGPUMemory(GPUVAddr addr, u64 size) {
+void RasterizerVulkan::ModifyGPUMemory(size_t as_id, GPUVAddr addr, u64 size) {
{
std::scoped_lock lock{texture_cache.mutex};
- texture_cache.UnmapGPUMemory(addr, size);
+ texture_cache.UnmapGPUMemory(as_id, addr, size);
}
}
-void RasterizerVulkan::SignalSemaphore(GPUVAddr addr, u32 value) {
- if (!gpu.IsAsync()) {
- gpu_memory.Write<u32>(addr, value);
- return;
- }
- fence_manager.SignalSemaphore(addr, value);
+void RasterizerVulkan::SignalFence(std::function<void()>&& func) {
+ fence_manager.SignalFence(std::move(func));
+}
+
+void RasterizerVulkan::SyncOperation(std::function<void()>&& func) {
+ fence_manager.SyncOperation(std::move(func));
}
void RasterizerVulkan::SignalSyncPoint(u32 value) {
- if (!gpu.IsAsync()) {
- gpu.IncrementSyncPoint(value);
- return;
- }
fence_manager.SignalSyncPoint(value);
}
void RasterizerVulkan::SignalReference() {
- if (!gpu.IsAsync()) {
- return;
- }
fence_manager.SignalOrdering();
}
void RasterizerVulkan::ReleaseFences() {
- if (!gpu.IsAsync()) {
- return;
- }
fence_manager.WaitPendingFences();
}
@@ -552,13 +553,13 @@ Tegra::Engines::AccelerateDMAInterface& RasterizerVulkan::AccessAccelerateDMA()
}
void RasterizerVulkan::AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
- std::span<u8> memory) {
- auto cpu_addr = gpu_memory.GpuToCpuAddress(address);
+ std::span<const u8> memory) {
+ auto cpu_addr = gpu_memory->GpuToCpuAddress(address);
if (!cpu_addr) [[unlikely]] {
- gpu_memory.WriteBlock(address, memory.data(), copy_size);
+ gpu_memory->WriteBlock(address, memory.data(), copy_size);
return;
}
- gpu_memory.WriteBlockUnsafe(address, memory.data(), copy_size);
+ gpu_memory->WriteBlockUnsafe(address, memory.data(), copy_size);
{
std::unique_lock<std::mutex> lock{buffer_cache.mutex};
if (!buffer_cache.InlineMemory(*cpu_addr, copy_size, memory)) {
@@ -627,7 +628,7 @@ bool AccelerateDMA::BufferCopy(GPUVAddr src_address, GPUVAddr dest_address, u64
}
void RasterizerVulkan::UpdateDynamicStates() {
- auto& regs = maxwell3d.regs;
+ auto& regs = maxwell3d->regs;
UpdateViewportsState(regs);
UpdateScissorsState(regs);
UpdateDepthBias(regs);
@@ -651,24 +652,24 @@ void RasterizerVulkan::UpdateDynamicStates() {
}
void RasterizerVulkan::BeginTransformFeedback() {
- const auto& regs = maxwell3d.regs;
- if (regs.tfb_enabled == 0) {
+ const auto& regs = maxwell3d->regs;
+ if (regs.transform_feedback_enabled == 0) {
return;
}
if (!device.IsExtTransformFeedbackSupported()) {
LOG_ERROR(Render_Vulkan, "Transform feedbacks used but not supported");
return;
}
- UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationControl) ||
- regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::TesselationEval) ||
- regs.IsShaderConfigEnabled(Maxwell::ShaderProgram::Geometry));
+ UNIMPLEMENTED_IF(regs.IsShaderConfigEnabled(Maxwell::ShaderType::TessellationInit) ||
+ regs.IsShaderConfigEnabled(Maxwell::ShaderType::Tessellation) ||
+ regs.IsShaderConfigEnabled(Maxwell::ShaderType::Geometry));
scheduler.Record(
[](vk::CommandBuffer cmdbuf) { cmdbuf.BeginTransformFeedbackEXT(0, 0, nullptr, nullptr); });
}
void RasterizerVulkan::EndTransformFeedback() {
- const auto& regs = maxwell3d.regs;
- if (regs.tfb_enabled == 0) {
+ const auto& regs = maxwell3d->regs;
+ if (regs.transform_feedback_enabled == 0) {
return;
}
if (!device.IsExtTransformFeedbackSupported()) {
@@ -748,11 +749,11 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) {
if (!state_tracker.TouchDepthBias()) {
return;
}
- float units = regs.polygon_offset_units / 2.0f;
- const bool is_d24 = regs.zeta.format == Tegra::DepthFormat::S8_UINT_Z24_UNORM ||
- regs.zeta.format == Tegra::DepthFormat::D24X8_UNORM ||
- regs.zeta.format == Tegra::DepthFormat::D24S8_UNORM ||
- regs.zeta.format == Tegra::DepthFormat::D24C8_UNORM;
+ float units = regs.depth_bias / 2.0f;
+ const bool is_d24 = regs.zeta.format == Tegra::DepthFormat::Z24_UNORM_S8_UINT ||
+ regs.zeta.format == Tegra::DepthFormat::X8Z24_UNORM ||
+ regs.zeta.format == Tegra::DepthFormat::S8Z24_UNORM ||
+ regs.zeta.format == Tegra::DepthFormat::V8Z24_UNORM;
if (is_d24 && !device.SupportsD24DepthBuffer()) {
// the base formulas can be obtained from here:
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias
@@ -760,8 +761,8 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) {
static_cast<double>(1ULL << (32 - 24)) / (static_cast<double>(0x1.ep+127));
units = static_cast<float>(static_cast<double>(units) * rescale_factor);
}
- scheduler.Record([constant = units, clamp = regs.polygon_offset_clamp,
- factor = regs.polygon_offset_factor](vk::CommandBuffer cmdbuf) {
+ scheduler.Record([constant = units, clamp = regs.depth_bias_clamp,
+ factor = regs.slope_scale_depth_bias](vk::CommandBuffer cmdbuf) {
cmdbuf.SetDepthBias(constant, clamp, factor);
});
}
@@ -791,8 +792,8 @@ void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs)
if (regs.stencil_two_side_enable) {
// Separate values per face
scheduler.Record(
- [front_ref = regs.stencil_front_func_ref, front_write_mask = regs.stencil_front_mask,
- front_test_mask = regs.stencil_front_func_mask, back_ref = regs.stencil_back_func_ref,
+ [front_ref = regs.stencil_front_ref, front_write_mask = regs.stencil_front_mask,
+ front_test_mask = regs.stencil_front_func_mask, back_ref = regs.stencil_back_ref,
back_write_mask = regs.stencil_back_mask,
back_test_mask = regs.stencil_back_func_mask](vk::CommandBuffer cmdbuf) {
// Front face
@@ -807,7 +808,7 @@ void RasterizerVulkan::UpdateStencilFaces(Tegra::Engines::Maxwell3D::Regs& regs)
});
} else {
// Front face defines both faces
- scheduler.Record([ref = regs.stencil_front_func_ref, write_mask = regs.stencil_front_mask,
+ scheduler.Record([ref = regs.stencil_front_ref, write_mask = regs.stencil_front_mask,
test_mask = regs.stencil_front_func_mask](vk::CommandBuffer cmdbuf) {
cmdbuf.SetStencilReference(VK_STENCIL_FACE_FRONT_AND_BACK, ref);
cmdbuf.SetStencilWriteMask(VK_STENCIL_FACE_FRONT_AND_BACK, write_mask);
@@ -820,7 +821,8 @@ void RasterizerVulkan::UpdateLineWidth(Tegra::Engines::Maxwell3D::Regs& regs) {
if (!state_tracker.TouchLineWidth()) {
return;
}
- const float width = regs.line_smooth_enable ? regs.line_width_smooth : regs.line_width_aliased;
+ const float width =
+ regs.line_anti_alias_enable ? regs.line_width_smooth : regs.line_width_aliased;
scheduler.Record([width](vk::CommandBuffer cmdbuf) { cmdbuf.SetLineWidth(width); });
}
@@ -828,10 +830,10 @@ void RasterizerVulkan::UpdateCullMode(Tegra::Engines::Maxwell3D::Regs& regs) {
if (!state_tracker.TouchCullMode()) {
return;
}
- scheduler.Record(
- [enabled = regs.cull_test_enabled, cull_face = regs.cull_face](vk::CommandBuffer cmdbuf) {
- cmdbuf.SetCullModeEXT(enabled ? MaxwellToVK::CullFace(cull_face) : VK_CULL_MODE_NONE);
- });
+ scheduler.Record([enabled = regs.gl_cull_test_enabled,
+ cull_face = regs.gl_cull_face](vk::CommandBuffer cmdbuf) {
+ cmdbuf.SetCullModeEXT(enabled ? MaxwellToVK::CullFace(cull_face) : VK_CULL_MODE_NONE);
+ });
}
void RasterizerVulkan::UpdateDepthBoundsTestEnable(Tegra::Engines::Maxwell3D::Regs& regs) {
@@ -880,8 +882,8 @@ void RasterizerVulkan::UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs) {
return;
}
- VkFrontFace front_face = MaxwellToVK::FrontFace(regs.front_face);
- if (regs.screen_y_control.triangle_rast_flip != 0) {
+ VkFrontFace front_face = MaxwellToVK::FrontFace(regs.gl_front_face);
+ if (regs.window_origin.flip_y != 0) {
front_face = front_face == VK_FRONT_FACE_CLOCKWISE ? VK_FRONT_FACE_COUNTER_CLOCKWISE
: VK_FRONT_FACE_CLOCKWISE;
}
@@ -893,16 +895,16 @@ void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) {
if (!state_tracker.TouchStencilOp()) {
return;
}
- const Maxwell::StencilOp fail = regs.stencil_front_op_fail;
- const Maxwell::StencilOp zfail = regs.stencil_front_op_zfail;
- const Maxwell::StencilOp zpass = regs.stencil_front_op_zpass;
- const Maxwell::ComparisonOp compare = regs.stencil_front_func_func;
+ const Maxwell::StencilOp::Op fail = regs.stencil_front_op.fail;
+ const Maxwell::StencilOp::Op zfail = regs.stencil_front_op.zfail;
+ const Maxwell::StencilOp::Op zpass = regs.stencil_front_op.zpass;
+ const Maxwell::ComparisonOp compare = regs.stencil_front_op.func;
if (regs.stencil_two_side_enable) {
// Separate stencil op per face
- const Maxwell::StencilOp back_fail = regs.stencil_back_op_fail;
- const Maxwell::StencilOp back_zfail = regs.stencil_back_op_zfail;
- const Maxwell::StencilOp back_zpass = regs.stencil_back_op_zpass;
- const Maxwell::ComparisonOp back_compare = regs.stencil_back_func_func;
+ const Maxwell::StencilOp::Op back_fail = regs.stencil_back_op.fail;
+ const Maxwell::StencilOp::Op back_zfail = regs.stencil_back_op.zfail;
+ const Maxwell::StencilOp::Op back_zpass = regs.stencil_back_op.zpass;
+ const Maxwell::ComparisonOp back_compare = regs.stencil_back_op.func;
scheduler.Record([fail, zfail, zpass, compare, back_fail, back_zfail, back_zpass,
back_compare](vk::CommandBuffer cmdbuf) {
cmdbuf.SetStencilOpEXT(VK_STENCIL_FACE_FRONT_BIT, MaxwellToVK::StencilOp(fail),
@@ -933,7 +935,7 @@ void RasterizerVulkan::UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs&
}
void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs) {
- auto& dirty{maxwell3d.dirty.flags};
+ auto& dirty{maxwell3d->dirty.flags};
if (!dirty[Dirty::VertexInput]) {
return;
}
@@ -974,15 +976,15 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
dirty[Dirty::VertexBinding0 + index] = false;
const u32 binding{static_cast<u32>(index)};
- const auto& input_binding{regs.vertex_array[binding]};
- const bool is_instanced{regs.instanced_arrays.IsInstancingEnabled(binding)};
+ const auto& input_binding{regs.vertex_streams[binding]};
+ const bool is_instanced{regs.vertex_stream_instances.IsInstancingEnabled(binding)};
bindings.push_back({
.sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT,
.pNext = nullptr,
.binding = binding,
.stride = input_binding.stride,
.inputRate = is_instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX,
- .divisor = is_instanced ? input_binding.divisor : 1,
+ .divisor = is_instanced ? input_binding.frequency : 1,
});
}
scheduler.Record([bindings, attributes](vk::CommandBuffer cmdbuf) {
@@ -990,4 +992,54 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
});
}
+void RasterizerVulkan::InitializeChannel(Tegra::Control::ChannelState& channel) {
+ CreateChannel(channel);
+ {
+ std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ texture_cache.CreateChannel(channel);
+ buffer_cache.CreateChannel(channel);
+ }
+ pipeline_cache.CreateChannel(channel);
+ query_cache.CreateChannel(channel);
+ state_tracker.SetupTables(channel);
+}
+
+void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
+ const s32 channel_id = channel.bind_id;
+ BindToChannel(channel_id);
+ {
+ std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ texture_cache.BindToChannel(channel_id);
+ buffer_cache.BindToChannel(channel_id);
+ }
+ pipeline_cache.BindToChannel(channel_id);
+ query_cache.BindToChannel(channel_id);
+ state_tracker.ChangeChannel(channel);
+ state_tracker.InvalidateState();
+}
+
+void RasterizerVulkan::ReleaseChannel(s32 channel_id) {
+ EraseChannel(channel_id);
+ {
+ std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
+ texture_cache.EraseChannel(channel_id);
+ buffer_cache.EraseChannel(channel_id);
+ }
+ pipeline_cache.EraseChannel(channel_id);
+ query_cache.EraseChannel(channel_id);
+}
+
+void RasterizerVulkan::BindInlineIndexBuffer() {
+ if (maxwell3d->inline_index_draw_indexes.empty()) {
+ return;
+ }
+ const auto data_count = static_cast<u32>(maxwell3d->inline_index_draw_indexes.size());
+ auto buffer = buffer_cache_runtime.UploadStagingBuffer(data_count);
+ std::memcpy(buffer.mapped_span.data(), maxwell3d->inline_index_draw_indexes.data(), data_count);
+ buffer_cache_runtime.BindIndexBuffer(
+ maxwell3d->regs.draw.topology, maxwell3d->regs.index_buffer.format,
+ maxwell3d->regs.index_buffer.first, maxwell3d->regs.index_buffer.count, buffer.buffer,
+ static_cast<u32>(buffer.offset), data_count);
+}
+
} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 0370ea39b..b0bc306f5 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -8,6 +8,7 @@
#include <boost/container/static_vector.hpp>
#include "common/common_types.h"
+#include "video_core/control/channel_state_cache.h"
#include "video_core/engines/maxwell_dma.h"
#include "video_core/rasterizer_accelerated.h"
#include "video_core/rasterizer_interface.h"
@@ -54,16 +55,16 @@ private:
BufferCache& buffer_cache;
};
-class RasterizerVulkan final : public VideoCore::RasterizerAccelerated {
+class RasterizerVulkan final : public VideoCore::RasterizerAccelerated,
+ protected VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo> {
public:
explicit RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
- Tegra::MemoryManager& gpu_memory_, Core::Memory::Memory& cpu_memory_,
- ScreenInfo& screen_info_, const Device& device_,
- MemoryAllocator& memory_allocator_, StateTracker& state_tracker_,
- Scheduler& scheduler_);
+ Core::Memory::Memory& cpu_memory_, ScreenInfo& screen_info_,
+ const Device& device_, MemoryAllocator& memory_allocator_,
+ StateTracker& state_tracker_, Scheduler& scheduler_);
~RasterizerVulkan() override;
- void Draw(bool is_indexed, bool is_instanced) override;
+ void Draw(bool is_indexed, u32 instance_count) override;
void Clear() override;
void DispatchCompute() override;
void ResetCounter(VideoCore::QueryType type) override;
@@ -75,10 +76,11 @@ public:
bool MustFlushRegion(VAddr addr, u64 size) override;
void InvalidateRegion(VAddr addr, u64 size) override;
void OnCPUWrite(VAddr addr, u64 size) override;
- void SyncGuestHost() override;
+ void InvalidateGPUCache() override;
void UnmapMemory(VAddr addr, u64 size) override;
- void ModifyGPUMemory(GPUVAddr addr, u64 size) override;
- void SignalSemaphore(GPUVAddr addr, u32 value) override;
+ void ModifyGPUMemory(size_t as_id, GPUVAddr addr, u64 size) override;
+ void SignalFence(std::function<void()>&& func) override;
+ void SyncOperation(std::function<void()>&& func) override;
void SignalSyncPoint(u32 value) override;
void SignalReference() override;
void ReleaseFences() override;
@@ -93,12 +95,18 @@ public:
const Tegra::Engines::Fermi2D::Config& copy_config) override;
Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override;
void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
- std::span<u8> memory) override;
+ std::span<const u8> memory) override;
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
u32 pixel_stride) override;
void LoadDiskResources(u64 title_id, std::stop_token stop_loading,
const VideoCore::DiskResourceLoadCallback& callback) override;
+ void InitializeChannel(Tegra::Control::ChannelState& channel) override;
+
+ void BindChannel(Tegra::Control::ChannelState& channel) override;
+
+ void ReleaseChannel(s32 channel_id) override;
+
private:
static constexpr size_t MAX_TEXTURES = 192;
static constexpr size_t MAX_IMAGES = 48;
@@ -133,10 +141,9 @@ private:
void UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs);
+ void BindInlineIndexBuffer();
+
Tegra::GPU& gpu;
- Tegra::MemoryManager& gpu_memory;
- Tegra::Engines::Maxwell3D& maxwell3d;
- Tegra::Engines::KeplerCompute& kepler_compute;
ScreenInfo& screen_info;
const Device& device;
@@ -148,7 +155,6 @@ private:
DescriptorPool descriptor_pool;
UpdateDescriptorQueue update_descriptor_queue;
BlitImageHelper blit_image;
- ASTCDecoderPass astc_decoder_pass;
RenderPassCache render_pass_cache;
TextureCacheRuntime texture_cache_runtime;
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp
index a331ff37e..7934f2a51 100644
--- a/src/video_core/renderer_vulkan/vk_scheduler.cpp
+++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp
@@ -136,9 +136,10 @@ bool Scheduler::UpdateRescaling(bool is_rescaling) {
}
void Scheduler::WorkerThread(std::stop_token stop_token) {
- Common::SetCurrentThreadName("yuzu:VulkanWorker");
+ Common::SetCurrentThreadName("VulkanWorker");
do {
std::unique_ptr<CommandChunk> work;
+ bool has_submit{false};
{
std::unique_lock lock{work_mutex};
if (work_queue.empty()) {
@@ -150,9 +151,10 @@ void Scheduler::WorkerThread(std::stop_token stop_token) {
}
work = std::move(work_queue.front());
work_queue.pop();
+
+ has_submit = work->HasSubmit();
+ work->ExecuteAll(current_cmdbuf);
}
- const bool has_submit = work->HasSubmit();
- work->ExecuteAll(current_cmdbuf);
if (has_submit) {
AllocateWorkerCommandBuffer();
}
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h
index c04aad08f..929216749 100644
--- a/src/video_core/renderer_vulkan/vk_scheduler.h
+++ b/src/video_core/renderer_vulkan/vk_scheduler.h
@@ -144,7 +144,6 @@ private:
using FuncType = TypedCommand<T>;
static_assert(sizeof(FuncType) < sizeof(data), "Lambda is too large");
- recorded_counts++;
command_offset = Common::AlignUp(command_offset, alignof(FuncType));
if (command_offset > sizeof(data) - sizeof(FuncType)) {
return false;
@@ -166,7 +165,7 @@ private:
}
bool Empty() const {
- return recorded_counts == 0;
+ return command_offset == 0;
}
bool HasSubmit() const {
@@ -177,7 +176,6 @@ private:
Command* first = nullptr;
Command* last = nullptr;
- size_t recorded_counts = 0;
size_t command_offset = 0;
bool submit = false;
alignas(std::max_align_t) std::array<u8, 0x8000> data{};
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
index 9ad096431..b87c3be66 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
@@ -7,9 +7,9 @@
#include "common/common_types.h"
#include "core/core.h"
+#include "video_core/control/channel_state.h"
#include "video_core/dirty_flags.h"
#include "video_core/engines/maxwell_3d.h"
-#include "video_core/gpu.h"
#include "video_core/renderer_vulkan/vk_state_tracker.h"
#define OFF(field_name) MAXWELL3D_REG_INDEX(field_name)
@@ -51,8 +51,8 @@ Flags MakeInvalidationFlags() {
void SetupDirtyViewports(Tables& tables) {
FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports);
FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports);
- tables[0][OFF(viewport_transform_enabled)] = Viewports;
- tables[1][OFF(screen_y_control)] = Viewports;
+ tables[0][OFF(viewport_scale_offset_enbled)] = Viewports;
+ tables[1][OFF(window_origin)] = Viewports;
}
void SetupDirtyScissors(Tables& tables) {
@@ -61,9 +61,9 @@ void SetupDirtyScissors(Tables& tables) {
void SetupDirtyDepthBias(Tables& tables) {
auto& table = tables[0];
- table[OFF(polygon_offset_units)] = DepthBias;
- table[OFF(polygon_offset_clamp)] = DepthBias;
- table[OFF(polygon_offset_factor)] = DepthBias;
+ table[OFF(depth_bias)] = DepthBias;
+ table[OFF(depth_bias_clamp)] = DepthBias;
+ table[OFF(slope_scale_depth_bias)] = DepthBias;
}
void SetupDirtyBlendConstants(Tables& tables) {
@@ -77,10 +77,10 @@ void SetupDirtyDepthBounds(Tables& tables) {
void SetupDirtyStencilProperties(Tables& tables) {
auto& table = tables[0];
table[OFF(stencil_two_side_enable)] = StencilProperties;
- table[OFF(stencil_front_func_ref)] = StencilProperties;
+ table[OFF(stencil_front_ref)] = StencilProperties;
table[OFF(stencil_front_mask)] = StencilProperties;
table[OFF(stencil_front_func_mask)] = StencilProperties;
- table[OFF(stencil_back_func_ref)] = StencilProperties;
+ table[OFF(stencil_back_ref)] = StencilProperties;
table[OFF(stencil_back_mask)] = StencilProperties;
table[OFF(stencil_back_func_mask)] = StencilProperties;
}
@@ -92,8 +92,8 @@ void SetupDirtyLineWidth(Tables& tables) {
void SetupDirtyCullMode(Tables& tables) {
auto& table = tables[0];
- table[OFF(cull_face)] = CullMode;
- table[OFF(cull_test_enabled)] = CullMode;
+ table[OFF(gl_cull_face)] = CullMode;
+ table[OFF(gl_cull_test_enabled)] = CullMode;
}
void SetupDirtyDepthBoundsEnable(Tables& tables) {
@@ -114,20 +114,20 @@ void SetupDirtyDepthCompareOp(Tables& tables) {
void SetupDirtyFrontFace(Tables& tables) {
auto& table = tables[0];
- table[OFF(front_face)] = FrontFace;
- table[OFF(screen_y_control)] = FrontFace;
+ table[OFF(gl_front_face)] = FrontFace;
+ table[OFF(window_origin)] = FrontFace;
}
void SetupDirtyStencilOp(Tables& tables) {
auto& table = tables[0];
- table[OFF(stencil_front_op_fail)] = StencilOp;
- table[OFF(stencil_front_op_zfail)] = StencilOp;
- table[OFF(stencil_front_op_zpass)] = StencilOp;
- table[OFF(stencil_front_func_func)] = StencilOp;
- table[OFF(stencil_back_op_fail)] = StencilOp;
- table[OFF(stencil_back_op_zfail)] = StencilOp;
- table[OFF(stencil_back_op_zpass)] = StencilOp;
- table[OFF(stencil_back_func_func)] = StencilOp;
+ table[OFF(stencil_front_op.fail)] = StencilOp;
+ table[OFF(stencil_front_op.zfail)] = StencilOp;
+ table[OFF(stencil_front_op.zpass)] = StencilOp;
+ table[OFF(stencil_front_op.func)] = StencilOp;
+ table[OFF(stencil_back_op.fail)] = StencilOp;
+ table[OFF(stencil_back_op.zfail)] = StencilOp;
+ table[OFF(stencil_back_op.zpass)] = StencilOp;
+ table[OFF(stencil_back_op.func)] = StencilOp;
// Table 0 is used by StencilProperties
tables[1][OFF(stencil_two_side_enable)] = StencilOp;
@@ -139,10 +139,10 @@ void SetupDirtyStencilTestEnable(Tables& tables) {
void SetupDirtyBlending(Tables& tables) {
tables[0][OFF(color_mask_common)] = Blending;
- tables[0][OFF(independent_blend_enable)] = Blending;
+ tables[0][OFF(blend_per_target_enabled)] = Blending;
FillBlock(tables[0], OFF(color_mask), NUM(color_mask), Blending);
FillBlock(tables[0], OFF(blend), NUM(blend), Blending);
- FillBlock(tables[0], OFF(independent_blend), NUM(independent_blend), Blending);
+ FillBlock(tables[0], OFF(blend_per_target), NUM(blend_per_target), Blending);
}
void SetupDirtyViewportSwizzles(Tables& tables) {
@@ -166,17 +166,16 @@ void SetupDirtyVertexBindings(Tables& tables) {
static constexpr size_t divisor_offset = 3;
for (size_t i = 0; i < Regs::NumVertexArrays; ++i) {
const u8 flag = static_cast<u8>(VertexBinding0 + i);
- tables[0][OFF(instanced_arrays) + i] = VertexInput;
- tables[1][OFF(instanced_arrays) + i] = flag;
- tables[0][OFF(vertex_array) + i * NUM(vertex_array[0]) + divisor_offset] = VertexInput;
- tables[1][OFF(vertex_array) + i * NUM(vertex_array[0]) + divisor_offset] = flag;
+ tables[0][OFF(vertex_stream_instances) + i] = VertexInput;
+ tables[1][OFF(vertex_stream_instances) + i] = flag;
+ tables[0][OFF(vertex_streams) + i * NUM(vertex_streams[0]) + divisor_offset] = VertexInput;
+ tables[1][OFF(vertex_streams) + i * NUM(vertex_streams[0]) + divisor_offset] = flag;
}
}
} // Anonymous namespace
-StateTracker::StateTracker(Tegra::GPU& gpu)
- : flags{gpu.Maxwell3D().dirty.flags}, invalidation_flags{MakeInvalidationFlags()} {
- auto& tables{gpu.Maxwell3D().dirty.tables};
+void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) {
+ auto& tables{channel_state.maxwell_3d->dirty.tables};
SetupDirtyFlags(tables);
SetupDirtyViewports(tables);
SetupDirtyScissors(tables);
@@ -199,4 +198,15 @@ StateTracker::StateTracker(Tegra::GPU& gpu)
SetupDirtyVertexBindings(tables);
}
+void StateTracker::ChangeChannel(Tegra::Control::ChannelState& channel_state) {
+ flags = &channel_state.maxwell_3d->dirty.flags;
+}
+
+void StateTracker::InvalidateState() {
+ flags->set();
+}
+
+StateTracker::StateTracker()
+ : flags{&default_flags}, default_flags{}, invalidation_flags{MakeInvalidationFlags()} {}
+
} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h
index a85bc1c10..2296dea60 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.h
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.h
@@ -10,6 +10,12 @@
#include "video_core/dirty_flags.h"
#include "video_core/engines/maxwell_3d.h"
+namespace Tegra {
+namespace Control {
+struct ChannelState;
+}
+} // namespace Tegra
+
namespace Vulkan {
namespace Dirty {
@@ -53,19 +59,19 @@ class StateTracker {
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
public:
- explicit StateTracker(Tegra::GPU& gpu);
+ explicit StateTracker();
void InvalidateCommandBufferState() {
- flags |= invalidation_flags;
+ (*flags) |= invalidation_flags;
current_topology = INVALID_TOPOLOGY;
}
void InvalidateViewports() {
- flags[Dirty::Viewports] = true;
+ (*flags)[Dirty::Viewports] = true;
}
void InvalidateScissors() {
- flags[Dirty::Scissors] = true;
+ (*flags)[Dirty::Scissors] = true;
}
bool TouchViewports() {
@@ -139,16 +145,23 @@ public:
return has_changed;
}
+ void SetupTables(Tegra::Control::ChannelState& channel_state);
+
+ void ChangeChannel(Tegra::Control::ChannelState& channel_state);
+
+ void InvalidateState();
+
private:
static constexpr auto INVALID_TOPOLOGY = static_cast<Maxwell::PrimitiveTopology>(~0u);
bool Exchange(std::size_t id, bool new_value) const noexcept {
- const bool is_dirty = flags[id];
- flags[id] = new_value;
+ const bool is_dirty = (*flags)[id];
+ (*flags)[id] = new_value;
return is_dirty;
}
- Tegra::Engines::Maxwell3D::DirtyState::Flags& flags;
+ Tegra::Engines::Maxwell3D::DirtyState::Flags* flags;
+ Tegra::Engines::Maxwell3D::DirtyState::Flags default_flags;
Tegra::Engines::Maxwell3D::DirtyState::Flags invalidation_flags;
Maxwell::PrimitiveTopology current_topology = INVALID_TOPOLOGY;
};
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp
index a69ae7725..706d9ba74 100644
--- a/src/video_core/renderer_vulkan/vk_swapchain.cpp
+++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp
@@ -36,7 +36,8 @@ VkPresentModeKHR ChooseSwapPresentMode(vk::Span<VkPresentModeKHR> modes) {
// Mailbox (triple buffering) doesn't lock the application like fifo (vsync),
// prefer it if vsync option is not selected
const auto found_mailbox = std::find(modes.begin(), modes.end(), VK_PRESENT_MODE_MAILBOX_KHR);
- if (found_mailbox != modes.end() && !Settings::values.use_vsync.GetValue()) {
+ if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Borderless &&
+ found_mailbox != modes.end() && !Settings::values.use_vsync.GetValue()) {
return VK_PRESENT_MODE_MAILBOX_KHR;
}
if (!Settings::values.use_speed_limit.GetValue()) {
@@ -156,8 +157,16 @@ void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, u3
present_mode = ChooseSwapPresentMode(present_modes);
u32 requested_image_count{capabilities.minImageCount + 1};
- if (capabilities.maxImageCount > 0 && requested_image_count > capabilities.maxImageCount) {
- requested_image_count = capabilities.maxImageCount;
+ // Ensure Tripple buffering if possible.
+ if (capabilities.maxImageCount > 0) {
+ if (requested_image_count > capabilities.maxImageCount) {
+ requested_image_count = capabilities.maxImageCount;
+ } else {
+ requested_image_count =
+ std::max(requested_image_count, std::min(3U, capabilities.maxImageCount));
+ }
+ } else {
+ requested_image_count = std::max(requested_image_count, 3U);
}
VkSwapchainCreateInfoKHR swapchain_ci{
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index caca79d79..853b80d8a 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -592,7 +592,7 @@ void TryTransformSwizzleIfNeeded(PixelFormat format, std::array<SwizzleSource, 4
case PixelFormat::A5B5G5R1_UNORM:
std::ranges::transform(swizzle, swizzle.begin(), SwapSpecial);
break;
- case PixelFormat::R4G4_UNORM:
+ case PixelFormat::G4R4_UNORM:
std::ranges::transform(swizzle, swizzle.begin(), SwapGreenRed);
break;
default:
@@ -791,12 +791,17 @@ TextureCacheRuntime::TextureCacheRuntime(const Device& device_, Scheduler& sched
MemoryAllocator& memory_allocator_,
StagingBufferPool& staging_buffer_pool_,
BlitImageHelper& blit_image_helper_,
- ASTCDecoderPass& astc_decoder_pass_,
- RenderPassCache& render_pass_cache_)
+ RenderPassCache& render_pass_cache_,
+ DescriptorPool& descriptor_pool,
+ UpdateDescriptorQueue& update_descriptor_queue)
: device{device_}, scheduler{scheduler_}, memory_allocator{memory_allocator_},
staging_buffer_pool{staging_buffer_pool_}, blit_image_helper{blit_image_helper_},
- astc_decoder_pass{astc_decoder_pass_}, render_pass_cache{render_pass_cache_},
- resolution{Settings::values.resolution_info} {}
+ render_pass_cache{render_pass_cache_}, resolution{Settings::values.resolution_info} {
+ if (Settings::values.accelerate_astc) {
+ astc_decoder_pass.emplace(device, scheduler, descriptor_pool, staging_buffer_pool,
+ update_descriptor_queue, memory_allocator);
+ }
+}
void TextureCacheRuntime::Finish() {
scheduler.Finish();
@@ -1474,13 +1479,14 @@ bool Image::BlitScaleHelper(bool scale_up) {
};
const VkExtent2D extent{
.width = std::max(scaled_width, info.size.width),
- .height = std::max(scaled_height, info.size.width),
+ .height = std::max(scaled_height, info.size.height),
};
auto* view_ptr = blit_view.get();
if (aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT) {
if (!blit_framebuffer) {
- blit_framebuffer = std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent);
+ blit_framebuffer =
+ std::make_unique<Framebuffer>(*runtime, view_ptr, nullptr, extent, scale_up);
}
const auto color_view = blit_view->Handle(Shader::TextureType::Color2D);
@@ -1488,7 +1494,8 @@ bool Image::BlitScaleHelper(bool scale_up) {
src_region, operation, BLIT_OPERATION);
} else if (aspect_mask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
if (!blit_framebuffer) {
- blit_framebuffer = std::make_unique<Framebuffer>(*runtime, nullptr, view_ptr, extent);
+ blit_framebuffer =
+ std::make_unique<Framebuffer>(*runtime, nullptr, view_ptr, extent, scale_up);
}
runtime->blit_image_helper.BlitDepthStencil(blit_framebuffer.get(), blit_view->DepthView(),
blit_view->StencilView(), dst_region,
@@ -1756,34 +1763,42 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM
.width = key.size.width,
.height = key.size.height,
}} {
- CreateFramebuffer(runtime, color_buffers, depth_buffer);
+ CreateFramebuffer(runtime, color_buffers, depth_buffer, key.is_rescaled);
if (runtime.device.HasDebuggingToolAttached()) {
framebuffer.SetObjectNameEXT(VideoCommon::Name(key).c_str());
}
}
Framebuffer::Framebuffer(TextureCacheRuntime& runtime, ImageView* color_buffer,
- ImageView* depth_buffer, VkExtent2D extent)
+ ImageView* depth_buffer, VkExtent2D extent, bool is_rescaled)
: render_area{extent} {
std::array<ImageView*, NUM_RT> color_buffers{color_buffer};
- CreateFramebuffer(runtime, color_buffers, depth_buffer);
+ CreateFramebuffer(runtime, color_buffers, depth_buffer, is_rescaled);
}
Framebuffer::~Framebuffer() = default;
void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
std::span<ImageView*, NUM_RT> color_buffers,
- ImageView* depth_buffer) {
+ ImageView* depth_buffer, bool is_rescaled) {
std::vector<VkImageView> attachments;
RenderPassKey renderpass_key{};
s32 num_layers = 1;
+ const auto& resolution = runtime.resolution;
+
+ u32 width = std::numeric_limits<u32>::max();
+ u32 height = std::numeric_limits<u32>::max();
for (size_t index = 0; index < NUM_RT; ++index) {
const ImageView* const color_buffer = color_buffers[index];
if (!color_buffer) {
renderpass_key.color_formats[index] = PixelFormat::Invalid;
continue;
}
+ width = std::min(width, is_rescaled ? resolution.ScaleUp(color_buffer->size.width)
+ : color_buffer->size.width);
+ height = std::min(height, is_rescaled ? resolution.ScaleUp(color_buffer->size.height)
+ : color_buffer->size.height);
attachments.push_back(color_buffer->RenderTarget());
renderpass_key.color_formats[index] = color_buffer->format;
num_layers = std::max(num_layers, color_buffer->range.extent.layers);
@@ -1794,6 +1809,10 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
}
const size_t num_colors = attachments.size();
if (depth_buffer) {
+ width = std::min(width, is_rescaled ? resolution.ScaleUp(depth_buffer->size.width)
+ : depth_buffer->size.width);
+ height = std::min(height, is_rescaled ? resolution.ScaleUp(depth_buffer->size.height)
+ : depth_buffer->size.height);
attachments.push_back(depth_buffer->RenderTarget());
renderpass_key.depth_format = depth_buffer->format;
num_layers = std::max(num_layers, depth_buffer->range.extent.layers);
@@ -1810,6 +1829,8 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
renderpass_key.samples = samples;
renderpass = runtime.render_pass_cache.Get(renderpass_key);
+ render_area.width = std::min(render_area.width, width);
+ render_area.height = std::min(render_area.height, height);
num_color_buffers = static_cast<u32>(num_colors);
framebuffer = runtime.device.GetLogical().CreateFramebuffer({
@@ -1829,7 +1850,7 @@ void TextureCacheRuntime::AccelerateImageUpload(
Image& image, const StagingBufferRef& map,
std::span<const VideoCommon::SwizzleParameters> swizzles) {
if (IsPixelFormatASTC(image.info.format)) {
- return astc_decoder_pass.Assemble(image, map, swizzles);
+ return astc_decoder_pass->Assemble(image, map, swizzles);
}
ASSERT(false);
}
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index 69f06ee7b..7ec0df134 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -6,6 +6,7 @@
#include <span>
#include "shader_recompiler/shader_info.h"
+#include "video_core/renderer_vulkan/vk_compute_pass.h"
#include "video_core/renderer_vulkan/vk_staging_buffer_pool.h"
#include "video_core/texture_cache/image_view_base.h"
#include "video_core/texture_cache/texture_cache_base.h"
@@ -25,14 +26,15 @@ using VideoCommon::RenderTargets;
using VideoCommon::SlotVector;
using VideoCore::Surface::PixelFormat;
-class ASTCDecoderPass;
class BlitImageHelper;
+class DescriptorPool;
class Device;
class Image;
class ImageView;
class Framebuffer;
class RenderPassCache;
class StagingBufferPool;
+class UpdateDescriptorQueue;
class Scheduler;
class TextureCacheRuntime {
@@ -41,8 +43,9 @@ public:
MemoryAllocator& memory_allocator_,
StagingBufferPool& staging_buffer_pool_,
BlitImageHelper& blit_image_helper_,
- ASTCDecoderPass& astc_decoder_pass_,
- RenderPassCache& render_pass_cache_);
+ RenderPassCache& render_pass_cache_,
+ DescriptorPool& descriptor_pool,
+ UpdateDescriptorQueue& update_descriptor_queue);
void Finish();
@@ -97,8 +100,8 @@ public:
MemoryAllocator& memory_allocator;
StagingBufferPool& staging_buffer_pool;
BlitImageHelper& blit_image_helper;
- ASTCDecoderPass& astc_decoder_pass;
RenderPassCache& render_pass_cache;
+ std::optional<ASTCDecoderPass> astc_decoder_pass;
const Settings::ResolutionScalingInfo& resolution;
constexpr static size_t indexing_slots = 8 * sizeof(size_t);
@@ -268,7 +271,7 @@ public:
ImageView* depth_buffer, const VideoCommon::RenderTargets& key);
explicit Framebuffer(TextureCacheRuntime& runtime, ImageView* color_buffer,
- ImageView* depth_buffer, VkExtent2D extent);
+ ImageView* depth_buffer, VkExtent2D extent, bool is_rescaled);
~Framebuffer();
@@ -279,7 +282,8 @@ public:
Framebuffer& operator=(Framebuffer&&) = default;
void CreateFramebuffer(TextureCacheRuntime& runtime,
- std::span<ImageView*, NUM_RT> color_buffers, ImageView* depth_buffer);
+ std::span<ImageView*, NUM_RT> color_buffers, ImageView* depth_buffer,
+ bool is_rescaled = false);
[[nodiscard]] VkFramebuffer Handle() const noexcept {
return *framebuffer;
diff --git a/src/video_core/shader_cache.cpp b/src/video_core/shader_cache.cpp
index 164e4ee0e..d9482371b 100644
--- a/src/video_core/shader_cache.cpp
+++ b/src/video_core/shader_cache.cpp
@@ -8,6 +8,7 @@
#include "common/assert.h"
#include "shader_recompiler/frontend/maxwell/control_flow.h"
#include "shader_recompiler/object_pool.h"
+#include "video_core/control/channel_state.h"
#include "video_core/dirty_flags.h"
#include "video_core/engines/kepler_compute.h"
#include "video_core/engines/maxwell_3d.h"
@@ -33,29 +34,25 @@ void ShaderCache::SyncGuestHost() {
RemovePendingShaders();
}
-ShaderCache::ShaderCache(VideoCore::RasterizerInterface& rasterizer_,
- Tegra::MemoryManager& gpu_memory_, Tegra::Engines::Maxwell3D& maxwell3d_,
- Tegra::Engines::KeplerCompute& kepler_compute_)
- : gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, kepler_compute{kepler_compute_},
- rasterizer{rasterizer_} {}
+ShaderCache::ShaderCache(VideoCore::RasterizerInterface& rasterizer_) : rasterizer{rasterizer_} {}
bool ShaderCache::RefreshStages(std::array<u64, 6>& unique_hashes) {
- auto& dirty{maxwell3d.dirty.flags};
+ auto& dirty{maxwell3d->dirty.flags};
if (!dirty[VideoCommon::Dirty::Shaders]) {
return last_shaders_valid;
}
dirty[VideoCommon::Dirty::Shaders] = false;
- const GPUVAddr base_addr{maxwell3d.regs.code_address.CodeAddress()};
+ const GPUVAddr base_addr{maxwell3d->regs.program_region.Address()};
for (size_t index = 0; index < Tegra::Engines::Maxwell3D::Regs::MaxShaderProgram; ++index) {
- if (!maxwell3d.regs.IsShaderConfigEnabled(index)) {
+ if (!maxwell3d->regs.IsShaderConfigEnabled(index)) {
unique_hashes[index] = 0;
continue;
}
- const auto& shader_config{maxwell3d.regs.shader_config[index]};
- const auto program{static_cast<Tegra::Engines::Maxwell3D::Regs::ShaderProgram>(index)};
+ const auto& shader_config{maxwell3d->regs.pipelines[index]};
+ const auto program{static_cast<Tegra::Engines::Maxwell3D::Regs::ShaderType>(index)};
const GPUVAddr shader_addr{base_addr + shader_config.offset};
- const std::optional<VAddr> cpu_shader_addr{gpu_memory.GpuToCpuAddress(shader_addr)};
+ const std::optional<VAddr> cpu_shader_addr{gpu_memory->GpuToCpuAddress(shader_addr)};
if (!cpu_shader_addr) {
LOG_ERROR(HW_GPU, "Invalid GPU address for shader 0x{:016x}", shader_addr);
last_shaders_valid = false;
@@ -64,7 +61,7 @@ bool ShaderCache::RefreshStages(std::array<u64, 6>& unique_hashes) {
const ShaderInfo* shader_info{TryGet(*cpu_shader_addr)};
if (!shader_info) {
const u32 start_address{shader_config.offset};
- GraphicsEnvironment env{maxwell3d, gpu_memory, program, base_addr, start_address};
+ GraphicsEnvironment env{*maxwell3d, *gpu_memory, program, base_addr, start_address};
shader_info = MakeShaderInfo(env, *cpu_shader_addr);
}
shader_infos[index] = shader_info;
@@ -75,10 +72,10 @@ bool ShaderCache::RefreshStages(std::array<u64, 6>& unique_hashes) {
}
const ShaderInfo* ShaderCache::ComputeShader() {
- const GPUVAddr program_base{kepler_compute.regs.code_loc.Address()};
- const auto& qmd{kepler_compute.launch_description};
+ const GPUVAddr program_base{kepler_compute->regs.code_loc.Address()};
+ const auto& qmd{kepler_compute->launch_description};
const GPUVAddr shader_addr{program_base + qmd.program_start};
- const std::optional<VAddr> cpu_shader_addr{gpu_memory.GpuToCpuAddress(shader_addr)};
+ const std::optional<VAddr> cpu_shader_addr{gpu_memory->GpuToCpuAddress(shader_addr)};
if (!cpu_shader_addr) {
LOG_ERROR(HW_GPU, "Invalid GPU address for shader 0x{:016x}", shader_addr);
return nullptr;
@@ -86,22 +83,22 @@ const ShaderInfo* ShaderCache::ComputeShader() {
if (const ShaderInfo* const shader = TryGet(*cpu_shader_addr)) {
return shader;
}
- ComputeEnvironment env{kepler_compute, gpu_memory, program_base, qmd.program_start};
+ ComputeEnvironment env{*kepler_compute, *gpu_memory, program_base, qmd.program_start};
return MakeShaderInfo(env, *cpu_shader_addr);
}
void ShaderCache::GetGraphicsEnvironments(GraphicsEnvironments& result,
const std::array<u64, NUM_PROGRAMS>& unique_hashes) {
size_t env_index{};
- const GPUVAddr base_addr{maxwell3d.regs.code_address.CodeAddress()};
+ const GPUVAddr base_addr{maxwell3d->regs.program_region.Address()};
for (size_t index = 0; index < NUM_PROGRAMS; ++index) {
if (unique_hashes[index] == 0) {
continue;
}
- const auto program{static_cast<Tegra::Engines::Maxwell3D::Regs::ShaderProgram>(index)};
+ const auto program{static_cast<Tegra::Engines::Maxwell3D::Regs::ShaderType>(index)};
auto& env{result.envs[index]};
- const u32 start_address{maxwell3d.regs.shader_config[index].offset};
- env = GraphicsEnvironment{maxwell3d, gpu_memory, program, base_addr, start_address};
+ const u32 start_address{maxwell3d->regs.pipelines[index].offset};
+ env = GraphicsEnvironment{*maxwell3d, *gpu_memory, program, base_addr, start_address};
env.SetCachedSize(shader_infos[index]->size_bytes);
result.env_ptrs[env_index++] = &env;
}
diff --git a/src/video_core/shader_cache.h b/src/video_core/shader_cache.h
index f67cea8c4..a4391202d 100644
--- a/src/video_core/shader_cache.h
+++ b/src/video_core/shader_cache.h
@@ -12,6 +12,7 @@
#include <vector>
#include "common/common_types.h"
+#include "video_core/control/channel_state_cache.h"
#include "video_core/rasterizer_interface.h"
#include "video_core/shader_environment.h"
@@ -19,6 +20,10 @@ namespace Tegra {
class MemoryManager;
}
+namespace Tegra::Control {
+struct ChannelState;
+}
+
namespace VideoCommon {
class GenericEnvironment;
@@ -28,7 +33,7 @@ struct ShaderInfo {
size_t size_bytes{};
};
-class ShaderCache {
+class ShaderCache : public VideoCommon::ChannelSetupCaches<VideoCommon::ChannelInfo> {
static constexpr u64 YUZU_PAGEBITS = 14;
static constexpr u64 YUZU_PAGESIZE = u64(1) << YUZU_PAGEBITS;
@@ -71,9 +76,7 @@ protected:
}
};
- explicit ShaderCache(VideoCore::RasterizerInterface& rasterizer_,
- Tegra::MemoryManager& gpu_memory_, Tegra::Engines::Maxwell3D& maxwell3d_,
- Tegra::Engines::KeplerCompute& kepler_compute_);
+ explicit ShaderCache(VideoCore::RasterizerInterface& rasterizer_);
/// @brief Update the hashes and information of shader stages
/// @param unique_hashes Shader hashes to store into when a stage is enabled
@@ -88,10 +91,6 @@ protected:
void GetGraphicsEnvironments(GraphicsEnvironments& result,
const std::array<u64, NUM_PROGRAMS>& unique_hashes);
- Tegra::MemoryManager& gpu_memory;
- Tegra::Engines::Maxwell3D& maxwell3d;
- Tegra::Engines::KeplerCompute& kepler_compute;
-
std::array<const ShaderInfo*, NUM_PROGRAMS> shader_infos{};
bool last_shaders_valid = false;
diff --git a/src/video_core/shader_environment.cpp b/src/video_core/shader_environment.cpp
index c903975fc..63bcf9337 100644
--- a/src/video_core/shader_environment.cpp
+++ b/src/video_core/shader_environment.cpp
@@ -252,34 +252,34 @@ Shader::TextureType GenericEnvironment::ReadTextureTypeImpl(GPUVAddr tic_addr, u
GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_,
Tegra::MemoryManager& gpu_memory_,
- Maxwell::ShaderProgram program, GPUVAddr program_base_,
+ Maxwell::ShaderType program, GPUVAddr program_base_,
u32 start_address_)
: GenericEnvironment{gpu_memory_, program_base_, start_address_}, maxwell3d{&maxwell3d_} {
gpu_memory->ReadBlock(program_base + start_address, &sph, sizeof(sph));
initial_offset = sizeof(sph);
- gp_passthrough_mask = maxwell3d->regs.gp_passthrough_mask;
+ gp_passthrough_mask = maxwell3d->regs.post_vtg_shader_attrib_skip_mask;
switch (program) {
- case Maxwell::ShaderProgram::VertexA:
+ case Maxwell::ShaderType::VertexA:
stage = Shader::Stage::VertexA;
stage_index = 0;
break;
- case Maxwell::ShaderProgram::VertexB:
+ case Maxwell::ShaderType::VertexB:
stage = Shader::Stage::VertexB;
stage_index = 0;
break;
- case Maxwell::ShaderProgram::TesselationControl:
+ case Maxwell::ShaderType::TessellationInit:
stage = Shader::Stage::TessellationControl;
stage_index = 1;
break;
- case Maxwell::ShaderProgram::TesselationEval:
+ case Maxwell::ShaderType::Tessellation:
stage = Shader::Stage::TessellationEval;
stage_index = 2;
break;
- case Maxwell::ShaderProgram::Geometry:
+ case Maxwell::ShaderType::Geometry:
stage = Shader::Stage::Geometry;
stage_index = 3;
break;
- case Maxwell::ShaderProgram::Fragment:
+ case Maxwell::ShaderType::Pixel:
stage = Shader::Stage::Fragment;
stage_index = 4;
break;
@@ -290,7 +290,7 @@ GraphicsEnvironment::GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_,
const u64 local_size{sph.LocalMemorySize()};
ASSERT(local_size <= std::numeric_limits<u32>::max());
local_memory_size = static_cast<u32>(local_size) + sph.common3.shader_local_memory_crs_size;
- texture_bound = maxwell3d->regs.tex_cb_index;
+ texture_bound = maxwell3d->regs.bindless_texture_const_buffer_slot;
}
u32 GraphicsEnvironment::ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) {
@@ -306,8 +306,9 @@ u32 GraphicsEnvironment::ReadCbufValue(u32 cbuf_index, u32 cbuf_offset) {
Shader::TextureType GraphicsEnvironment::ReadTextureType(u32 handle) {
const auto& regs{maxwell3d->regs};
- const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex};
- return ReadTextureTypeImpl(regs.tic.Address(), regs.tic.limit, via_header_index, handle);
+ const bool via_header_index{regs.sampler_binding == Maxwell::SamplerBinding::ViaHeaderBinding};
+ return ReadTextureTypeImpl(regs.tex_header.Address(), regs.tex_header.limit, via_header_index,
+ handle);
}
u32 GraphicsEnvironment::ReadViewportTransformState() {
diff --git a/src/video_core/shader_environment.h b/src/video_core/shader_environment.h
index a0659fd7c..a05833f38 100644
--- a/src/video_core/shader_environment.h
+++ b/src/video_core/shader_environment.h
@@ -95,7 +95,7 @@ public:
explicit GraphicsEnvironment() = default;
explicit GraphicsEnvironment(Tegra::Engines::Maxwell3D& maxwell3d_,
Tegra::MemoryManager& gpu_memory_,
- Tegra::Engines::Maxwell3D::Regs::ShaderProgram program,
+ Tegra::Engines::Maxwell3D::Regs::ShaderType program,
GPUVAddr program_base_, u32 start_address_);
~GraphicsEnvironment() override = default;
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp
index 079d5f028..6bd133d10 100644
--- a/src/video_core/surface.cpp
+++ b/src/video_core/surface.cpp
@@ -73,17 +73,17 @@ bool SurfaceTargetIsArray(SurfaceTarget target) {
PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) {
switch (format) {
- case Tegra::DepthFormat::S8_UINT_Z24_UNORM:
+ case Tegra::DepthFormat::Z24_UNORM_S8_UINT:
return PixelFormat::S8_UINT_D24_UNORM;
- case Tegra::DepthFormat::D24S8_UNORM:
+ case Tegra::DepthFormat::S8Z24_UNORM:
return PixelFormat::D24_UNORM_S8_UINT;
- case Tegra::DepthFormat::D32_FLOAT:
+ case Tegra::DepthFormat::Z32_FLOAT:
return PixelFormat::D32_FLOAT;
- case Tegra::DepthFormat::D16_UNORM:
+ case Tegra::DepthFormat::Z16_UNORM:
return PixelFormat::D16_UNORM;
case Tegra::DepthFormat::S8_UINT:
return PixelFormat::S8_UINT;
- case Tegra::DepthFormat::D32_FLOAT_S8X24_UINT:
+ case Tegra::DepthFormat::Z32_FLOAT_X24S8_UINT:
return PixelFormat::D32_FLOAT_S8_UINT;
default:
UNIMPLEMENTED_MSG("Unimplemented format={}", format);
@@ -117,9 +117,9 @@ PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format)
return PixelFormat::R32G32_UINT;
case Tegra::RenderTargetFormat::R16G16B16X16_FLOAT:
return PixelFormat::R16G16B16X16_FLOAT;
- case Tegra::RenderTargetFormat::B8G8R8A8_UNORM:
+ case Tegra::RenderTargetFormat::A8R8G8B8_UNORM:
return PixelFormat::B8G8R8A8_UNORM;
- case Tegra::RenderTargetFormat::B8G8R8A8_SRGB:
+ case Tegra::RenderTargetFormat::A8R8G8B8_SRGB:
return PixelFormat::B8G8R8A8_SRGB;
case Tegra::RenderTargetFormat::A2B10G10R10_UNORM:
return PixelFormat::A2B10G10R10_UNORM;
@@ -247,6 +247,8 @@ bool IsPixelFormatASTC(PixelFormat format) {
case PixelFormat::ASTC_2D_6X6_UNORM:
case PixelFormat::ASTC_2D_6X6_SRGB:
case PixelFormat::ASTC_2D_10X6_UNORM:
+ case PixelFormat::ASTC_2D_10X5_UNORM:
+ case PixelFormat::ASTC_2D_10X5_SRGB:
case PixelFormat::ASTC_2D_10X10_UNORM:
case PixelFormat::ASTC_2D_10X10_SRGB:
case PixelFormat::ASTC_2D_12X12_UNORM:
@@ -276,6 +278,7 @@ bool IsPixelFormatSRGB(PixelFormat format) {
case PixelFormat::ASTC_2D_5X5_SRGB:
case PixelFormat::ASTC_2D_10X8_SRGB:
case PixelFormat::ASTC_2D_6X6_SRGB:
+ case PixelFormat::ASTC_2D_10X5_SRGB:
case PixelFormat::ASTC_2D_10X10_SRGB:
case PixelFormat::ASTC_2D_12X12_SRGB:
case PixelFormat::ASTC_2D_8X6_SRGB:
diff --git a/src/video_core/surface.h b/src/video_core/surface.h
index 16273f185..57ca7f597 100644
--- a/src/video_core/surface.h
+++ b/src/video_core/surface.h
@@ -82,7 +82,7 @@ enum class PixelFormat {
BC3_SRGB,
BC7_SRGB,
A4B4G4R4_UNORM,
- R4G4_UNORM,
+ G4R4_UNORM,
ASTC_2D_4X4_SRGB,
ASTC_2D_8X8_SRGB,
ASTC_2D_8X5_SRGB,
@@ -94,6 +94,8 @@ enum class PixelFormat {
ASTC_2D_6X6_UNORM,
ASTC_2D_6X6_SRGB,
ASTC_2D_10X6_UNORM,
+ ASTC_2D_10X5_UNORM,
+ ASTC_2D_10X5_SRGB,
ASTC_2D_10X10_UNORM,
ASTC_2D_10X10_SRGB,
ASTC_2D_12X12_UNORM,
@@ -216,7 +218,7 @@ constexpr std::array<u8, MaxPixelFormat> BLOCK_WIDTH_TABLE = {{
4, // BC3_SRGB
4, // BC7_SRGB
1, // A4B4G4R4_UNORM
- 1, // R4G4_UNORM
+ 1, // G4R4_UNORM
4, // ASTC_2D_4X4_SRGB
8, // ASTC_2D_8X8_SRGB
8, // ASTC_2D_8X5_SRGB
@@ -228,6 +230,8 @@ constexpr std::array<u8, MaxPixelFormat> BLOCK_WIDTH_TABLE = {{
6, // ASTC_2D_6X6_UNORM
6, // ASTC_2D_6X6_SRGB
10, // ASTC_2D_10X6_UNORM
+ 10, // ASTC_2D_10X5_UNORM
+ 10, // ASTC_2D_10X5_SRGB
10, // ASTC_2D_10X10_UNORM
10, // ASTC_2D_10X10_SRGB
12, // ASTC_2D_12X12_UNORM
@@ -319,7 +323,7 @@ constexpr std::array<u8, MaxPixelFormat> BLOCK_HEIGHT_TABLE = {{
4, // BC3_SRGB
4, // BC7_SRGB
1, // A4B4G4R4_UNORM
- 1, // R4G4_UNORM
+ 1, // G4R4_UNORM
4, // ASTC_2D_4X4_SRGB
8, // ASTC_2D_8X8_SRGB
5, // ASTC_2D_8X5_SRGB
@@ -331,6 +335,8 @@ constexpr std::array<u8, MaxPixelFormat> BLOCK_HEIGHT_TABLE = {{
6, // ASTC_2D_6X6_UNORM
6, // ASTC_2D_6X6_SRGB
6, // ASTC_2D_10X6_UNORM
+ 5, // ASTC_2D_10X5_UNORM
+ 5, // ASTC_2D_10X5_SRGB
10, // ASTC_2D_10X10_UNORM
10, // ASTC_2D_10X10_SRGB
12, // ASTC_2D_12X12_UNORM
@@ -422,7 +428,7 @@ constexpr std::array<u8, MaxPixelFormat> BITS_PER_BLOCK_TABLE = {{
128, // BC3_SRGB
128, // BC7_UNORM
16, // A4B4G4R4_UNORM
- 8, // R4G4_UNORM
+ 8, // G4R4_UNORM
128, // ASTC_2D_4X4_SRGB
128, // ASTC_2D_8X8_SRGB
128, // ASTC_2D_8X5_SRGB
@@ -434,6 +440,8 @@ constexpr std::array<u8, MaxPixelFormat> BITS_PER_BLOCK_TABLE = {{
128, // ASTC_2D_6X6_UNORM
128, // ASTC_2D_6X6_SRGB
128, // ASTC_2D_10X6_UNORM
+ 128, // ASTC_2D_10X5_UNORM
+ 128, // ASTC_2D_10X5_SRGB
128, // ASTC_2D_10X10_UNORM
128, // ASTC_2D_10X10_SRGB
128, // ASTC_2D_12X12_UNORM
diff --git a/src/video_core/texture_cache/descriptor_table.h b/src/video_core/texture_cache/descriptor_table.h
index b18e3838f..ee4240288 100644
--- a/src/video_core/texture_cache/descriptor_table.h
+++ b/src/video_core/texture_cache/descriptor_table.h
@@ -18,7 +18,7 @@ class DescriptorTable {
public:
explicit DescriptorTable(Tegra::MemoryManager& gpu_memory_) : gpu_memory{gpu_memory_} {}
- [[nodiscard]] bool Synchornize(GPUVAddr gpu_addr, u32 limit) {
+ [[nodiscard]] bool Synchronize(GPUVAddr gpu_addr, u32 limit) {
[[likely]] if (current_gpu_addr == gpu_addr && current_limit == limit) {
return false;
}
diff --git a/src/video_core/texture_cache/format_lookup_table.cpp b/src/video_core/texture_cache/format_lookup_table.cpp
index 1412aa076..08aa8ca33 100644
--- a/src/video_core/texture_cache/format_lookup_table.cpp
+++ b/src/video_core/texture_cache/format_lookup_table.cpp
@@ -63,7 +63,7 @@ PixelFormat PixelFormatFromTextureInfo(TextureFormat format, ComponentType red,
case Hash(TextureFormat::A4B4G4R4, UNORM):
return PixelFormat::A4B4G4R4_UNORM;
case Hash(TextureFormat::G4R4, UNORM):
- return PixelFormat::R4G4_UNORM;
+ return PixelFormat::G4R4_UNORM;
case Hash(TextureFormat::A5B5G5R1, UNORM):
return PixelFormat::A5B5G5R1_UNORM;
case Hash(TextureFormat::R8, UNORM):
@@ -150,6 +150,8 @@ PixelFormat PixelFormatFromTextureInfo(TextureFormat format, ComponentType red,
return PixelFormat::D24_UNORM_S8_UINT;
case Hash(TextureFormat::D32S8, FLOAT, UINT, UNORM, UNORM, LINEAR):
return PixelFormat::D32_FLOAT_S8_UINT;
+ case Hash(TextureFormat::R32_B24G8, FLOAT, UINT, UNORM, UNORM, LINEAR):
+ return PixelFormat::D32_FLOAT_S8_UINT;
case Hash(TextureFormat::BC1_RGBA, UNORM, LINEAR):
return PixelFormat::BC1_RGBA_UNORM;
case Hash(TextureFormat::BC1_RGBA, UNORM, SRGB):
@@ -208,6 +210,10 @@ PixelFormat PixelFormatFromTextureInfo(TextureFormat format, ComponentType red,
return PixelFormat::ASTC_2D_6X6_SRGB;
case Hash(TextureFormat::ASTC_2D_10X6, UNORM, LINEAR):
return PixelFormat::ASTC_2D_10X6_UNORM;
+ case Hash(TextureFormat::ASTC_2D_10X5, UNORM, LINEAR):
+ return PixelFormat::ASTC_2D_10X5_UNORM;
+ case Hash(TextureFormat::ASTC_2D_10X5, UNORM, SRGB):
+ return PixelFormat::ASTC_2D_10X5_SRGB;
case Hash(TextureFormat::ASTC_2D_10X10, UNORM, LINEAR):
return PixelFormat::ASTC_2D_10X10_UNORM;
case Hash(TextureFormat::ASTC_2D_10X10, UNORM, SRGB):
diff --git a/src/video_core/texture_cache/formatter.h b/src/video_core/texture_cache/formatter.h
index 95a572604..acc854715 100644
--- a/src/video_core/texture_cache/formatter.h
+++ b/src/video_core/texture_cache/formatter.h
@@ -153,8 +153,8 @@ struct fmt::formatter<VideoCore::Surface::PixelFormat> : fmt::formatter<fmt::str
return "BC7_SRGB";
case PixelFormat::A4B4G4R4_UNORM:
return "A4B4G4R4_UNORM";
- case PixelFormat::R4G4_UNORM:
- return "R4G4_UNORM";
+ case PixelFormat::G4R4_UNORM:
+ return "G4R4_UNORM";
case PixelFormat::ASTC_2D_4X4_SRGB:
return "ASTC_2D_4X4_SRGB";
case PixelFormat::ASTC_2D_8X8_SRGB:
@@ -177,6 +177,10 @@ struct fmt::formatter<VideoCore::Surface::PixelFormat> : fmt::formatter<fmt::str
return "ASTC_2D_6X6_SRGB";
case PixelFormat::ASTC_2D_10X6_UNORM:
return "ASTC_2D_10X6_UNORM";
+ case PixelFormat::ASTC_2D_10X5_UNORM:
+ return "ASTC_2D_10X5_UNORM";
+ case PixelFormat::ASTC_2D_10X5_SRGB:
+ return "ASTC_2D_10X5_SRGB";
case PixelFormat::ASTC_2D_10X10_UNORM:
return "ASTC_2D_10X10_UNORM";
case PixelFormat::ASTC_2D_10X10_SRGB:
diff --git a/src/video_core/texture_cache/image_base.cpp b/src/video_core/texture_cache/image_base.cpp
index f61e09ac7..91512022f 100644
--- a/src/video_core/texture_cache/image_base.cpp
+++ b/src/video_core/texture_cache/image_base.cpp
@@ -7,6 +7,7 @@
#include <vector>
#include "common/common_types.h"
+#include "common/div_ceil.h"
#include "video_core/surface.h"
#include "video_core/texture_cache/formatter.h"
#include "video_core/texture_cache/image_base.h"
@@ -182,10 +183,6 @@ void AddImageAlias(ImageBase& lhs, ImageBase& rhs, ImageId lhs_id, ImageId rhs_i
};
const bool is_lhs_compressed = lhs_block.width > 1 || lhs_block.height > 1;
const bool is_rhs_compressed = rhs_block.width > 1 || rhs_block.height > 1;
- if (is_lhs_compressed && is_rhs_compressed) {
- LOG_ERROR(HW_GPU, "Compressed to compressed image aliasing is not implemented");
- return;
- }
const s32 lhs_mips = lhs.info.resources.levels;
const s32 rhs_mips = rhs.info.resources.levels;
const s32 num_mips = std::min(lhs_mips - base->level, rhs_mips);
@@ -199,12 +196,12 @@ void AddImageAlias(ImageBase& lhs, ImageBase& rhs, ImageId lhs_id, ImageId rhs_i
Extent3D lhs_size = MipSize(lhs.info.size, base->level + mip_level);
Extent3D rhs_size = MipSize(rhs.info.size, mip_level);
if (is_lhs_compressed) {
- lhs_size.width /= lhs_block.width;
- lhs_size.height /= lhs_block.height;
+ lhs_size.width = Common::DivCeil(lhs_size.width, lhs_block.width);
+ lhs_size.height = Common::DivCeil(lhs_size.height, lhs_block.height);
}
if (is_rhs_compressed) {
- rhs_size.width /= rhs_block.width;
- rhs_size.height /= rhs_block.height;
+ rhs_size.width = Common::DivCeil(rhs_size.width, rhs_block.width);
+ rhs_size.height = Common::DivCeil(rhs_size.height, rhs_block.height);
}
const Extent3D copy_size{
.width = std::min(lhs_size.width, rhs_size.width),
diff --git a/src/video_core/texture_cache/image_base.h b/src/video_core/texture_cache/image_base.h
index 1f85ec9da..620565684 100644
--- a/src/video_core/texture_cache/image_base.h
+++ b/src/video_core/texture_cache/image_base.h
@@ -88,6 +88,9 @@ struct ImageBase {
u32 scale_rating = 0;
u64 scale_tick = 0;
bool has_scaled = false;
+
+ size_t channel = 0;
+
ImageFlagBits flags = ImageFlagBits::CpuModified;
GPUVAddr gpu_addr = 0;
diff --git a/src/video_core/texture_cache/image_info.cpp b/src/video_core/texture_cache/image_info.cpp
index 6c073ee57..852ec2519 100644
--- a/src/video_core/texture_cache/image_info.cpp
+++ b/src/video_core/texture_cache/image_info.cpp
@@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
+#include <fmt/format.h>
+
#include "common/assert.h"
#include "video_core/surface.h"
#include "video_core/texture_cache/format_lookup_table.h"
@@ -12,6 +14,7 @@
namespace VideoCommon {
+using Tegra::Engines::Maxwell3D;
using Tegra::Texture::TextureType;
using Tegra::Texture::TICEntry;
using VideoCore::Surface::PixelFormat;
@@ -107,12 +110,13 @@ ImageInfo::ImageInfo(const TICEntry& config) noexcept {
}
}
-ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index) noexcept {
+ImageInfo::ImageInfo(const Maxwell3D::Regs& regs, size_t index) noexcept {
const auto& rt = regs.rt[index];
format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(rt.format);
rescaleable = false;
if (rt.tile_mode.is_pitch_linear) {
- ASSERT(rt.tile_mode.is_3d == 0);
+ ASSERT(rt.tile_mode.dim_control ==
+ Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesArray);
type = ImageType::Linear;
pitch = rt.width;
size = Extent3D{
@@ -124,15 +128,16 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index)
}
size.width = rt.width;
size.height = rt.height;
- layer_stride = rt.layer_stride * 4;
+ layer_stride = rt.array_pitch * 4;
maybe_unaligned_layer_stride = layer_stride;
- num_samples = NumSamples(regs.multisample_mode);
+ num_samples = NumSamples(regs.anti_alias_samples_mode);
block = Extent3D{
.width = rt.tile_mode.block_width,
.height = rt.tile_mode.block_height,
.depth = rt.tile_mode.block_depth,
};
- if (rt.tile_mode.is_3d) {
+ if (rt.tile_mode.dim_control ==
+ Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesDepth) {
type = ImageType::e3D;
size.depth = rt.depth;
} else {
@@ -146,31 +151,37 @@ ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs, size_t index)
ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept {
format = VideoCore::Surface::PixelFormatFromDepthFormat(regs.zeta.format);
- size.width = regs.zeta_width;
- size.height = regs.zeta_height;
+ size.width = regs.zeta_size.width;
+ size.height = regs.zeta_size.height;
rescaleable = false;
resources.levels = 1;
- layer_stride = regs.zeta.layer_stride * 4;
+ layer_stride = regs.zeta.array_pitch * 4;
maybe_unaligned_layer_stride = layer_stride;
- num_samples = NumSamples(regs.multisample_mode);
+ num_samples = NumSamples(regs.anti_alias_samples_mode);
block = Extent3D{
.width = regs.zeta.tile_mode.block_width,
.height = regs.zeta.tile_mode.block_height,
.depth = regs.zeta.tile_mode.block_depth,
};
if (regs.zeta.tile_mode.is_pitch_linear) {
- ASSERT(regs.zeta.tile_mode.is_3d == 0);
+ ASSERT(regs.zeta.tile_mode.dim_control ==
+ Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesArray);
type = ImageType::Linear;
pitch = size.width * BytesPerBlock(format);
- } else if (regs.zeta.tile_mode.is_3d) {
+ } else if (regs.zeta.tile_mode.dim_control ==
+ Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesDepth) {
ASSERT(regs.zeta.tile_mode.is_pitch_linear == 0);
+ ASSERT(regs.zeta_size.dim_control ==
+ Maxwell3D::Regs::ZetaSize::DimensionControl::ArraySizeOne);
type = ImageType::e3D;
- size.depth = regs.zeta_depth;
+ size.depth = regs.zeta_size.depth;
} else {
+ ASSERT(regs.zeta_size.dim_control ==
+ Maxwell3D::Regs::ZetaSize::DimensionControl::DepthDefinesArray);
rescaleable = block.depth == 0;
downscaleable = size.height > 512;
type = ImageType::e2D;
- resources.layers = regs.zeta_depth;
+ resources.layers = regs.zeta_size.depth;
}
}
diff --git a/src/video_core/texture_cache/render_targets.h b/src/video_core/texture_cache/render_targets.h
index da8ffe9ec..1efbd6507 100644
--- a/src/video_core/texture_cache/render_targets.h
+++ b/src/video_core/texture_cache/render_targets.h
@@ -26,6 +26,7 @@ struct RenderTargets {
ImageViewId depth_buffer_id{};
std::array<u8, NUM_RT> draw_buffers{};
Extent2D size{};
+ bool is_rescaled{};
};
} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp
new file mode 100644
index 000000000..8a9a32f44
--- /dev/null
+++ b/src/video_core/texture_cache/texture_cache.cpp
@@ -0,0 +1,15 @@
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "video_core/control/channel_state_cache.inc"
+#include "video_core/texture_cache/texture_cache_base.h"
+
+namespace VideoCommon {
+
+TextureCacheChannelInfo::TextureCacheChannelInfo(Tegra::Control::ChannelState& state) noexcept
+ : ChannelInfo(state), graphics_image_table{gpu_memory}, graphics_sampler_table{gpu_memory},
+ compute_image_table{gpu_memory}, compute_sampler_table{gpu_memory} {}
+
+template class VideoCommon::ChannelSetupCaches<VideoCommon::TextureCacheChannelInfo>;
+
+} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 1dbe01bc0..8ef75fe73 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -1,5 +1,5 @@
-// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
@@ -7,6 +7,7 @@
#include "common/alignment.h"
#include "common/settings.h"
+#include "video_core/control/channel_state.h"
#include "video_core/dirty_flags.h"
#include "video_core/engines/kepler_compute.h"
#include "video_core/texture_cache/image_view_base.h"
@@ -29,12 +30,8 @@ using VideoCore::Surface::SurfaceType;
using namespace Common::Literals;
template <class P>
-TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& rasterizer_,
- Tegra::Engines::Maxwell3D& maxwell3d_,
- Tegra::Engines::KeplerCompute& kepler_compute_,
- Tegra::MemoryManager& gpu_memory_)
- : runtime{runtime_}, rasterizer{rasterizer_}, maxwell3d{maxwell3d_},
- kepler_compute{kepler_compute_}, gpu_memory{gpu_memory_} {
+TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface& rasterizer_)
+ : runtime{runtime_}, rasterizer{rasterizer_} {
// Configure null sampler
TSCEntry sampler_descriptor{};
sampler_descriptor.min_filter.Assign(Tegra::Texture::TextureFilter::Linear);
@@ -93,7 +90,7 @@ void TextureCache<P>::RunGarbageCollector() {
const auto copies = FullDownloadCopies(image.info);
image.DownloadMemory(map, copies);
runtime.Finish();
- SwizzleImage(gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span);
+ SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span);
}
if (True(image.flags & ImageFlagBits::Tracked)) {
UntrackImage(image, image_id);
@@ -152,22 +149,24 @@ void TextureCache<P>::MarkModification(ImageId id) noexcept {
template <class P>
template <bool has_blacklists>
void TextureCache<P>::FillGraphicsImageViews(std::span<ImageViewInOut> views) {
- FillImageViews<has_blacklists>(graphics_image_table, graphics_image_view_ids, views);
+ FillImageViews<has_blacklists>(channel_state->graphics_image_table,
+ channel_state->graphics_image_view_ids, views);
}
template <class P>
void TextureCache<P>::FillComputeImageViews(std::span<ImageViewInOut> views) {
- FillImageViews<true>(compute_image_table, compute_image_view_ids, views);
+ FillImageViews<true>(channel_state->compute_image_table, channel_state->compute_image_view_ids,
+ views);
}
template <class P>
typename P::Sampler* TextureCache<P>::GetGraphicsSampler(u32 index) {
- if (index > graphics_sampler_table.Limit()) {
+ if (index > channel_state->graphics_sampler_table.Limit()) {
LOG_DEBUG(HW_GPU, "Invalid sampler index={}", index);
return &slot_samplers[NULL_SAMPLER_ID];
}
- const auto [descriptor, is_new] = graphics_sampler_table.Read(index);
- SamplerId& id = graphics_sampler_ids[index];
+ const auto [descriptor, is_new] = channel_state->graphics_sampler_table.Read(index);
+ SamplerId& id = channel_state->graphics_sampler_ids[index];
if (is_new) {
id = FindSampler(descriptor);
}
@@ -176,12 +175,12 @@ typename P::Sampler* TextureCache<P>::GetGraphicsSampler(u32 index) {
template <class P>
typename P::Sampler* TextureCache<P>::GetComputeSampler(u32 index) {
- if (index > compute_sampler_table.Limit()) {
+ if (index > channel_state->compute_sampler_table.Limit()) {
LOG_DEBUG(HW_GPU, "Invalid sampler index={}", index);
return &slot_samplers[NULL_SAMPLER_ID];
}
- const auto [descriptor, is_new] = compute_sampler_table.Read(index);
- SamplerId& id = compute_sampler_ids[index];
+ const auto [descriptor, is_new] = channel_state->compute_sampler_table.Read(index);
+ SamplerId& id = channel_state->compute_sampler_ids[index];
if (is_new) {
id = FindSampler(descriptor);
}
@@ -190,35 +189,38 @@ typename P::Sampler* TextureCache<P>::GetComputeSampler(u32 index) {
template <class P>
void TextureCache<P>::SynchronizeGraphicsDescriptors() {
- using SamplerIndex = Tegra::Engines::Maxwell3D::Regs::SamplerIndex;
- const bool linked_tsc = maxwell3d.regs.sampler_index == SamplerIndex::ViaHeaderIndex;
- const u32 tic_limit = maxwell3d.regs.tic.limit;
- const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d.regs.tsc.limit;
- if (graphics_sampler_table.Synchornize(maxwell3d.regs.tsc.Address(), tsc_limit)) {
- graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
+ using SamplerBinding = Tegra::Engines::Maxwell3D::Regs::SamplerBinding;
+ const bool linked_tsc = maxwell3d->regs.sampler_binding == SamplerBinding::ViaHeaderBinding;
+ const u32 tic_limit = maxwell3d->regs.tex_header.limit;
+ const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tex_sampler.limit;
+ if (channel_state->graphics_sampler_table.Synchronize(maxwell3d->regs.tex_sampler.Address(),
+ tsc_limit)) {
+ channel_state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
}
- if (graphics_image_table.Synchornize(maxwell3d.regs.tic.Address(), tic_limit)) {
- graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
+ if (channel_state->graphics_image_table.Synchronize(maxwell3d->regs.tex_header.Address(),
+ tic_limit)) {
+ channel_state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
}
}
template <class P>
void TextureCache<P>::SynchronizeComputeDescriptors() {
- const bool linked_tsc = kepler_compute.launch_description.linked_tsc;
- const u32 tic_limit = kepler_compute.regs.tic.limit;
- const u32 tsc_limit = linked_tsc ? tic_limit : kepler_compute.regs.tsc.limit;
- const GPUVAddr tsc_gpu_addr = kepler_compute.regs.tsc.Address();
- if (compute_sampler_table.Synchornize(tsc_gpu_addr, tsc_limit)) {
- compute_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
+ const bool linked_tsc = kepler_compute->launch_description.linked_tsc;
+ const u32 tic_limit = kepler_compute->regs.tic.limit;
+ const u32 tsc_limit = linked_tsc ? tic_limit : kepler_compute->regs.tsc.limit;
+ const GPUVAddr tsc_gpu_addr = kepler_compute->regs.tsc.Address();
+ if (channel_state->compute_sampler_table.Synchronize(tsc_gpu_addr, tsc_limit)) {
+ channel_state->compute_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
}
- if (compute_image_table.Synchornize(kepler_compute.regs.tic.Address(), tic_limit)) {
- compute_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
+ if (channel_state->compute_image_table.Synchronize(kepler_compute->regs.tic.Address(),
+ tic_limit)) {
+ channel_state->compute_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
}
}
template <class P>
bool TextureCache<P>::RescaleRenderTargets(bool is_clear) {
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
u32 scale_rating = 0;
bool rescaled = false;
std::array<ImageId, NUM_RT> tmp_color_images{};
@@ -315,7 +317,7 @@ bool TextureCache<P>::RescaleRenderTargets(bool is_clear) {
template <class P>
void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
using namespace VideoCommon::Dirty;
- auto& flags = maxwell3d.dirty.flags;
+ auto& flags = maxwell3d->dirty.flags;
if (!flags[Dirty::RenderTargets]) {
for (size_t index = 0; index < NUM_RT; ++index) {
ImageViewId& color_buffer_id = render_targets.color_buffer_ids[index];
@@ -342,7 +344,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
for (size_t index = 0; index < NUM_RT; ++index) {
- render_targets.draw_buffers[index] = static_cast<u8>(maxwell3d.regs.rt_control.Map(index));
+ render_targets.draw_buffers[index] = static_cast<u8>(maxwell3d->regs.rt_control.Map(index));
}
u32 up_scale = 1;
u32 down_shift = 0;
@@ -351,9 +353,10 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
down_shift = Settings::values.resolution_info.down_shift;
}
render_targets.size = Extent2D{
- (maxwell3d.regs.render_area.width * up_scale) >> down_shift,
- (maxwell3d.regs.render_area.height * up_scale) >> down_shift,
+ (maxwell3d->regs.surface_clip.width * up_scale) >> down_shift,
+ (maxwell3d->regs.surface_clip.height * up_scale) >> down_shift,
};
+ render_targets.is_rescaled = is_rescaling;
flags[Dirty::DepthBiasGlobal] = true;
}
@@ -439,7 +442,7 @@ void TextureCache<P>::WriteMemory(VAddr cpu_addr, size_t size) {
template <class P>
void TextureCache<P>::DownloadMemory(VAddr cpu_addr, size_t size) {
std::vector<ImageId> images;
- ForEachImageInRegion(cpu_addr, size, [this, &images](ImageId image_id, ImageBase& image) {
+ ForEachImageInRegion(cpu_addr, size, [&images](ImageId image_id, ImageBase& image) {
if (!image.IsSafeDownload()) {
return;
}
@@ -458,7 +461,7 @@ void TextureCache<P>::DownloadMemory(VAddr cpu_addr, size_t size) {
const auto copies = FullDownloadCopies(image.info);
image.DownloadMemory(map, copies);
runtime.Finish();
- SwizzleImage(gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span);
+ SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, map.mapped_span);
}
}
@@ -477,12 +480,20 @@ void TextureCache<P>::UnmapMemory(VAddr cpu_addr, size_t size) {
}
template <class P>
-void TextureCache<P>::UnmapGPUMemory(GPUVAddr gpu_addr, size_t size) {
+void TextureCache<P>::UnmapGPUMemory(size_t as_id, GPUVAddr gpu_addr, size_t size) {
std::vector<ImageId> deleted_images;
- ForEachImageInRegionGPU(gpu_addr, size,
+ ForEachImageInRegionGPU(as_id, gpu_addr, size,
[&](ImageId id, Image&) { deleted_images.push_back(id); });
for (const ImageId id : deleted_images) {
Image& image = slot_images[id];
+ if (True(image.flags & ImageFlagBits::CpuModified)) {
+ return;
+ }
+ image.flags |= ImageFlagBits::CpuModified;
+ if (True(image.flags & ImageFlagBits::Tracked)) {
+ UntrackImage(image, id);
+ }
+ /*
if (True(image.flags & ImageFlagBits::Remapped)) {
continue;
}
@@ -490,6 +501,7 @@ void TextureCache<P>::UnmapGPUMemory(GPUVAddr gpu_addr, size_t size) {
if (True(image.flags & ImageFlagBits::Tracked)) {
UntrackImage(image, id);
}
+ */
}
}
@@ -655,7 +667,7 @@ void TextureCache<P>::PopAsyncFlushes() {
for (const ImageId image_id : download_ids) {
const ImageBase& image = slot_images[image_id];
const auto copies = FullDownloadCopies(image.info);
- SwizzleImage(gpu_memory, image.gpu_addr, image.info, copies, download_span);
+ SwizzleImage(*gpu_memory, image.gpu_addr, image.info, copies, download_span);
download_map.offset += image.unswizzled_size_bytes;
download_span = download_span.subspan(image.unswizzled_size_bytes);
}
@@ -714,26 +726,26 @@ void TextureCache<P>::UploadImageContents(Image& image, StagingBuffer& staging)
const GPUVAddr gpu_addr = image.gpu_addr;
if (True(image.flags & ImageFlagBits::AcceleratedUpload)) {
- gpu_memory.ReadBlockUnsafe(gpu_addr, mapped_span.data(), mapped_span.size_bytes());
+ gpu_memory->ReadBlockUnsafe(gpu_addr, mapped_span.data(), mapped_span.size_bytes());
const auto uploads = FullUploadSwizzles(image.info);
runtime.AccelerateImageUpload(image, staging, uploads);
} else if (True(image.flags & ImageFlagBits::Converted)) {
std::vector<u8> unswizzled_data(image.unswizzled_size_bytes);
- auto copies = UnswizzleImage(gpu_memory, gpu_addr, image.info, unswizzled_data);
+ auto copies = UnswizzleImage(*gpu_memory, gpu_addr, image.info, unswizzled_data);
ConvertImage(unswizzled_data, image.info, mapped_span, copies);
image.UploadMemory(staging, copies);
} else {
- const auto copies = UnswizzleImage(gpu_memory, gpu_addr, image.info, mapped_span);
+ const auto copies = UnswizzleImage(*gpu_memory, gpu_addr, image.info, mapped_span);
image.UploadMemory(staging, copies);
}
}
template <class P>
ImageViewId TextureCache<P>::FindImageView(const TICEntry& config) {
- if (!IsValidEntry(gpu_memory, config)) {
+ if (!IsValidEntry(*gpu_memory, config)) {
return NULL_IMAGE_VIEW_ID;
}
- const auto [pair, is_new] = image_views.try_emplace(config);
+ const auto [pair, is_new] = channel_state->image_views.try_emplace(config);
ImageViewId& image_view_id = pair->second;
if (is_new) {
image_view_id = CreateImageView(config);
@@ -777,9 +789,9 @@ ImageId TextureCache<P>::FindOrInsertImage(const ImageInfo& info, GPUVAddr gpu_a
template <class P>
ImageId TextureCache<P>::FindImage(const ImageInfo& info, GPUVAddr gpu_addr,
RelaxedOptions options) {
- std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
+ std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
if (!cpu_addr) {
- cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr, CalculateGuestSizeInBytes(info));
+ cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr, CalculateGuestSizeInBytes(info));
if (!cpu_addr) {
return ImageId{};
}
@@ -860,7 +872,7 @@ void TextureCache<P>::InvalidateScale(Image& image) {
image.scale_tick = frame_tick + 1;
}
const std::span<const ImageViewId> image_view_ids = image.image_view_ids;
- auto& dirty = maxwell3d.dirty.flags;
+ auto& dirty = maxwell3d->dirty.flags;
dirty[Dirty::RenderTargets] = true;
dirty[Dirty::ZetaBuffer] = true;
for (size_t rt = 0; rt < NUM_RT; ++rt) {
@@ -880,12 +892,15 @@ void TextureCache<P>::InvalidateScale(Image& image) {
}
image.image_view_ids.clear();
image.image_view_infos.clear();
- if constexpr (ENABLE_VALIDATION) {
- std::ranges::fill(graphics_image_view_ids, CORRUPT_ID);
- std::ranges::fill(compute_image_view_ids, CORRUPT_ID);
+ for (size_t c : active_channel_ids) {
+ auto& channel_info = channel_storage[c];
+ if constexpr (ENABLE_VALIDATION) {
+ std::ranges::fill(channel_info.graphics_image_view_ids, CORRUPT_ID);
+ std::ranges::fill(channel_info.compute_image_view_ids, CORRUPT_ID);
+ }
+ channel_info.graphics_image_table.Invalidate();
+ channel_info.compute_image_table.Invalidate();
}
- graphics_image_table.Invalidate();
- compute_image_table.Invalidate();
has_deleted_images = true;
}
@@ -929,10 +944,10 @@ bool TextureCache<P>::ScaleDown(Image& image) {
template <class P>
ImageId TextureCache<P>::InsertImage(const ImageInfo& info, GPUVAddr gpu_addr,
RelaxedOptions options) {
- std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
+ std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
if (!cpu_addr) {
const auto size = CalculateGuestSizeInBytes(info);
- cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr, size);
+ cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr, size);
if (!cpu_addr) {
const VAddr fake_addr = ~(1ULL << 40ULL) + virtual_invalid_space;
virtual_invalid_space += Common::AlignUp(size, 32);
@@ -1050,7 +1065,7 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA
const ImageId new_image_id = slot_images.insert(runtime, new_info, gpu_addr, cpu_addr);
Image& new_image = slot_images[new_image_id];
- if (!gpu_memory.IsContinousRange(new_image.gpu_addr, new_image.guest_size_bytes)) {
+ if (!gpu_memory->IsContinousRange(new_image.gpu_addr, new_image.guest_size_bytes)) {
new_image.flags |= ImageFlagBits::Sparse;
}
@@ -1192,7 +1207,7 @@ SamplerId TextureCache<P>::FindSampler(const TSCEntry& config) {
if (std::ranges::all_of(config.raw, [](u64 value) { return value == 0; })) {
return NULL_SAMPLER_ID;
}
- const auto [pair, is_new] = samplers.try_emplace(config);
+ const auto [pair, is_new] = channel_state->samplers.try_emplace(config);
if (is_new) {
pair->second = slot_samplers.insert(runtime, config);
}
@@ -1201,7 +1216,7 @@ SamplerId TextureCache<P>::FindSampler(const TSCEntry& config) {
template <class P>
ImageViewId TextureCache<P>::FindColorBuffer(size_t index, bool is_clear) {
- const auto& regs = maxwell3d.regs;
+ const auto& regs = maxwell3d->regs;
if (index >= regs.rt_control.count) {
return ImageViewId{};
}
@@ -1219,7 +1234,7 @@ ImageViewId TextureCache<P>::FindColorBuffer(size_t index, bool is_clear) {
template <class P>
ImageViewId TextureCache<P>::FindDepthBuffer(bool is_clear) {
- const auto& regs = maxwell3d.regs;
+ const auto& regs = maxwell3d->regs;
if (!regs.zeta_enable) {
return ImageViewId{};
}
@@ -1316,11 +1331,17 @@ void TextureCache<P>::ForEachImageInRegion(VAddr cpu_addr, size_t size, Func&& f
template <class P>
template <typename Func>
-void TextureCache<P>::ForEachImageInRegionGPU(GPUVAddr gpu_addr, size_t size, Func&& func) {
+void TextureCache<P>::ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, size_t size,
+ Func&& func) {
using FuncReturn = typename std::invoke_result<Func, ImageId, Image&>::type;
static constexpr bool BOOL_BREAK = std::is_same_v<FuncReturn, bool>;
boost::container::small_vector<ImageId, 8> images;
- ForEachGPUPage(gpu_addr, size, [this, &images, gpu_addr, size, func](u64 page) {
+ auto storage_id = getStorageID(as_id);
+ if (!storage_id) {
+ return;
+ }
+ auto& gpu_page_table = gpu_page_table_storage[*storage_id];
+ ForEachGPUPage(gpu_addr, size, [this, gpu_page_table, &images, gpu_addr, size, func](u64 page) {
const auto it = gpu_page_table.find(page);
if (it == gpu_page_table.end()) {
if constexpr (BOOL_BREAK) {
@@ -1403,9 +1424,9 @@ template <typename Func>
void TextureCache<P>::ForEachSparseSegment(ImageBase& image, Func&& func) {
using FuncReturn = typename std::invoke_result<Func, GPUVAddr, VAddr, size_t>::type;
static constexpr bool RETURNS_BOOL = std::is_same_v<FuncReturn, bool>;
- const auto segments = gpu_memory.GetSubmappedRange(image.gpu_addr, image.guest_size_bytes);
+ const auto segments = gpu_memory->GetSubmappedRange(image.gpu_addr, image.guest_size_bytes);
for (const auto& [gpu_addr, size] : segments) {
- std::optional<VAddr> cpu_addr = gpu_memory.GpuToCpuAddress(gpu_addr);
+ std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
ASSERT(cpu_addr);
if constexpr (RETURNS_BOOL) {
if (func(gpu_addr, *cpu_addr, size)) {
@@ -1448,8 +1469,9 @@ void TextureCache<P>::RegisterImage(ImageId image_id) {
}
image.lru_index = lru_cache.Insert(image_id, frame_tick);
- ForEachGPUPage(image.gpu_addr, image.guest_size_bytes,
- [this, image_id](u64 page) { gpu_page_table[page].push_back(image_id); });
+ ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, image_id](u64 page) {
+ (*channel_state->gpu_page_table)[page].push_back(image_id);
+ });
if (False(image.flags & ImageFlagBits::Sparse)) {
auto map_id =
slot_map_views.insert(image.gpu_addr, image.cpu_addr, image.guest_size_bytes, image_id);
@@ -1480,9 +1502,9 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
image.flags &= ~ImageFlagBits::BadOverlap;
lru_cache.Free(image.lru_index);
const auto& clear_page_table =
- [this, image_id](
- u64 page,
- std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>>& selected_page_table) {
+ [image_id](u64 page,
+ std::unordered_map<u64, std::vector<ImageId>, Common::IdentityHash<u64>>&
+ selected_page_table) {
const auto page_it = selected_page_table.find(page);
if (page_it == selected_page_table.end()) {
ASSERT_MSG(false, "Unregistering unregistered page=0x{:x}", page << YUZU_PAGEBITS);
@@ -1497,8 +1519,9 @@ void TextureCache<P>::UnregisterImage(ImageId image_id) {
}
image_ids.erase(vector_it);
};
- ForEachGPUPage(image.gpu_addr, image.guest_size_bytes,
- [this, &clear_page_table](u64 page) { clear_page_table(page, gpu_page_table); });
+ ForEachGPUPage(image.gpu_addr, image.guest_size_bytes, [this, &clear_page_table](u64 page) {
+ clear_page_table(page, (*channel_state->gpu_page_table));
+ });
if (False(image.flags & ImageFlagBits::Sparse)) {
const auto map_id = image.map_view_id;
ForEachCPUPage(image.cpu_addr, image.guest_size_bytes, [this, map_id](u64 page) {
@@ -1631,7 +1654,7 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) {
ASSERT_MSG(False(image.flags & ImageFlagBits::Registered), "Image was not unregistered");
// Mark render targets as dirty
- auto& dirty = maxwell3d.dirty.flags;
+ auto& dirty = maxwell3d->dirty.flags;
dirty[Dirty::RenderTargets] = true;
dirty[Dirty::ZetaBuffer] = true;
for (size_t rt = 0; rt < NUM_RT; ++rt) {
@@ -1681,24 +1704,30 @@ void TextureCache<P>::DeleteImage(ImageId image_id, bool immediate_delete) {
if (alloc_images.empty()) {
image_allocs_table.erase(alloc_it);
}
- if constexpr (ENABLE_VALIDATION) {
- std::ranges::fill(graphics_image_view_ids, CORRUPT_ID);
- std::ranges::fill(compute_image_view_ids, CORRUPT_ID);
+ for (size_t c : active_channel_ids) {
+ auto& channel_info = channel_storage[c];
+ if constexpr (ENABLE_VALIDATION) {
+ std::ranges::fill(channel_info.graphics_image_view_ids, CORRUPT_ID);
+ std::ranges::fill(channel_info.compute_image_view_ids, CORRUPT_ID);
+ }
+ channel_info.graphics_image_table.Invalidate();
+ channel_info.compute_image_table.Invalidate();
}
- graphics_image_table.Invalidate();
- compute_image_table.Invalidate();
has_deleted_images = true;
}
template <class P>
void TextureCache<P>::RemoveImageViewReferences(std::span<const ImageViewId> removed_views) {
- auto it = image_views.begin();
- while (it != image_views.end()) {
- const auto found = std::ranges::find(removed_views, it->second);
- if (found != removed_views.end()) {
- it = image_views.erase(it);
- } else {
- ++it;
+ for (size_t c : active_channel_ids) {
+ auto& channel_info = channel_storage[c];
+ auto it = channel_info.image_views.begin();
+ while (it != channel_info.image_views.end()) {
+ const auto found = std::ranges::find(removed_views, it->second);
+ if (found != removed_views.end()) {
+ it = channel_info.image_views.erase(it);
+ } else {
+ ++it;
+ }
}
}
}
@@ -1729,6 +1758,7 @@ void TextureCache<P>::SynchronizeAliases(ImageId image_id) {
boost::container::small_vector<const AliasedImage*, 1> aliased_images;
Image& image = slot_images[image_id];
bool any_rescaled = True(image.flags & ImageFlagBits::Rescaled);
+ bool any_modified = True(image.flags & ImageFlagBits::GpuModified);
u64 most_recent_tick = image.modification_tick;
for (const AliasedImage& aliased : image.aliased_images) {
ImageBase& aliased_image = slot_images[aliased.id];
@@ -1736,9 +1766,7 @@ void TextureCache<P>::SynchronizeAliases(ImageId image_id) {
most_recent_tick = std::max(most_recent_tick, aliased_image.modification_tick);
aliased_images.push_back(&aliased);
any_rescaled |= True(aliased_image.flags & ImageFlagBits::Rescaled);
- if (True(aliased_image.flags & ImageFlagBits::GpuModified)) {
- image.flags |= ImageFlagBits::GpuModified;
- }
+ any_modified |= True(aliased_image.flags & ImageFlagBits::GpuModified);
}
}
if (aliased_images.empty()) {
@@ -1753,6 +1781,9 @@ void TextureCache<P>::SynchronizeAliases(ImageId image_id) {
}
}
image.modification_tick = most_recent_tick;
+ if (any_modified) {
+ image.flags |= ImageFlagBits::GpuModified;
+ }
std::ranges::sort(aliased_images, [this](const AliasedImage* lhs, const AliasedImage* rhs) {
const ImageBase& lhs_image = slot_images[lhs->id];
const ImageBase& rhs_image = slot_images[rhs->id];
@@ -1931,6 +1962,7 @@ std::pair<FramebufferId, ImageViewId> TextureCache<P>::RenderTargetFromImage(
.color_buffer_ids = {color_view_id},
.depth_buffer_id = depth_view_id,
.size = {extent.width >> samples_x, extent.height >> samples_y},
+ .is_rescaled = is_rescaled,
});
return {framebuffer_id, view_id};
}
@@ -1943,13 +1975,13 @@ bool TextureCache<P>::IsFullClear(ImageViewId id) {
const ImageViewBase& image_view = slot_image_views[id];
const ImageBase& image = slot_images[image_view.image_id];
const Extent3D size = image_view.size;
- const auto& regs = maxwell3d.regs;
+ const auto& regs = maxwell3d->regs;
const auto& scissor = regs.scissor_test[0];
if (image.info.resources.levels > 1 || image.info.resources.layers > 1) {
// Images with multiple resources can't be cleared in a single call
return false;
}
- if (regs.clear_flags.scissor == 0) {
+ if (regs.clear_control.use_scissor == 0) {
// If scissor testing is disabled, the clear is always full
return true;
}
@@ -1958,4 +1990,19 @@ bool TextureCache<P>::IsFullClear(ImageViewId id) {
scissor.max_y >= size.height;
}
+template <class P>
+void TextureCache<P>::CreateChannel(struct Tegra::Control::ChannelState& channel) {
+ VideoCommon::ChannelSetupCaches<TextureCacheChannelInfo>::CreateChannel(channel);
+ const auto it = channel_map.find(channel.bind_id);
+ auto* this_state = &channel_storage[it->second];
+ const auto& this_as_ref = address_spaces[channel.memory_manager->GetID()];
+ this_state->gpu_page_table = &gpu_page_table_storage[this_as_ref.storage_id];
+}
+
+/// Bind a channel for execution.
+template <class P>
+void TextureCache<P>::OnGPUASRegister([[maybe_unused]] size_t map_id) {
+ gpu_page_table_storage.emplace_back();
+}
+
} // namespace VideoCommon
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h
index 7e6c6cef2..2fa8445eb 100644
--- a/src/video_core/texture_cache/texture_cache_base.h
+++ b/src/video_core/texture_cache/texture_cache_base.h
@@ -1,8 +1,10 @@
-// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2021 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
+#include <deque>
+#include <limits>
#include <mutex>
#include <span>
#include <type_traits>
@@ -11,9 +13,11 @@
#include <queue>
#include "common/common_types.h"
+#include "common/hash.h"
#include "common/literals.h"
#include "common/lru_cache.h"
#include "video_core/compatible_formats.h"
+#include "video_core/control/channel_state_cache.h"
#include "video_core/delayed_destruction_ring.h"
#include "video_core/engines/fermi_2d.h"
#include "video_core/surface.h"
@@ -26,6 +30,10 @@
#include "video_core/texture_cache/types.h"
#include "video_core/textures/texture.h"
+namespace Tegra::Control {
+struct ChannelState;
+}
+
namespace VideoCommon {
using Tegra::Texture::SwizzleSource;
@@ -44,8 +52,35 @@ struct ImageViewInOut {
ImageViewId id{};
};
+using TextureCacheGPUMap = std::unordered_map<u64, std::vector<ImageId>, Common::IdentityHash<u64>>;
+
+class TextureCacheChannelInfo : public ChannelInfo {
+public:
+ TextureCacheChannelInfo() = delete;
+ TextureCacheChannelInfo(Tegra::Control::ChannelState& state) noexcept;
+ TextureCacheChannelInfo(const TextureCacheChannelInfo& state) = delete;
+ TextureCacheChannelInfo& operator=(const TextureCacheChannelInfo&) = delete;
+ TextureCacheChannelInfo(TextureCacheChannelInfo&& other) noexcept = default;
+ TextureCacheChannelInfo& operator=(TextureCacheChannelInfo&& other) noexcept = default;
+
+ DescriptorTable<TICEntry> graphics_image_table{gpu_memory};
+ DescriptorTable<TSCEntry> graphics_sampler_table{gpu_memory};
+ std::vector<SamplerId> graphics_sampler_ids;
+ std::vector<ImageViewId> graphics_image_view_ids;
+
+ DescriptorTable<TICEntry> compute_image_table{gpu_memory};
+ DescriptorTable<TSCEntry> compute_sampler_table{gpu_memory};
+ std::vector<SamplerId> compute_sampler_ids;
+ std::vector<ImageViewId> compute_image_view_ids;
+
+ std::unordered_map<TICEntry, ImageViewId> image_views;
+ std::unordered_map<TSCEntry, SamplerId> samplers;
+
+ TextureCacheGPUMap* gpu_page_table;
+};
+
template <class P>
-class TextureCache {
+class TextureCache : public VideoCommon::ChannelSetupCaches<TextureCacheChannelInfo> {
/// Address shift for caching images into a hash table
static constexpr u64 YUZU_PAGEBITS = 20;
@@ -58,6 +93,8 @@ class TextureCache {
/// True when the API can provide info about the memory of the device.
static constexpr bool HAS_DEVICE_MEMORY_INFO = P::HAS_DEVICE_MEMORY_INFO;
+ static constexpr size_t UNSET_CHANNEL{std::numeric_limits<size_t>::max()};
+
static constexpr s64 TARGET_THRESHOLD = 4_GiB;
static constexpr s64 DEFAULT_EXPECTED_MEMORY = 1_GiB + 125_MiB;
static constexpr s64 DEFAULT_CRITICAL_MEMORY = 1_GiB + 625_MiB;
@@ -77,16 +114,8 @@ class TextureCache {
PixelFormat src_format;
};
- template <typename T>
- struct IdentityHash {
- [[nodiscard]] size_t operator()(T value) const noexcept {
- return static_cast<size_t>(value);
- }
- };
-
public:
- explicit TextureCache(Runtime&, VideoCore::RasterizerInterface&, Tegra::Engines::Maxwell3D&,
- Tegra::Engines::KeplerCompute&, Tegra::MemoryManager&);
+ explicit TextureCache(Runtime&, VideoCore::RasterizerInterface&);
/// Notify the cache that a new frame has been queued
void TickFrame();
@@ -142,7 +171,7 @@ public:
void UnmapMemory(VAddr cpu_addr, size_t size);
/// Remove images in a region
- void UnmapGPUMemory(GPUVAddr gpu_addr, size_t size);
+ void UnmapGPUMemory(size_t as_id, GPUVAddr gpu_addr, size_t size);
/// Blit an image with the given parameters
void BlitImage(const Tegra::Engines::Fermi2D::Surface& dst,
@@ -171,6 +200,9 @@ public:
[[nodiscard]] bool IsRescaling(const ImageViewBase& image_view) const noexcept;
+ /// Create channel state.
+ void CreateChannel(Tegra::Control::ChannelState& channel) final override;
+
std::mutex mutex;
private:
@@ -205,6 +237,8 @@ private:
}
}
+ void OnGPUASRegister(size_t map_id) final override;
+
/// Runs the Garbage Collector.
void RunGarbageCollector();
@@ -273,7 +307,7 @@ private:
void ForEachImageInRegion(VAddr cpu_addr, size_t size, Func&& func);
template <typename Func>
- void ForEachImageInRegionGPU(GPUVAddr gpu_addr, size_t size, Func&& func);
+ void ForEachImageInRegionGPU(size_t as_id, GPUVAddr gpu_addr, size_t size, Func&& func);
template <typename Func>
void ForEachSparseImageInRegion(GPUVAddr gpu_addr, size_t size, Func&& func);
@@ -338,31 +372,16 @@ private:
u64 GetScaledImageSizeBytes(ImageBase& image);
Runtime& runtime;
- VideoCore::RasterizerInterface& rasterizer;
- Tegra::Engines::Maxwell3D& maxwell3d;
- Tegra::Engines::KeplerCompute& kepler_compute;
- Tegra::MemoryManager& gpu_memory;
- DescriptorTable<TICEntry> graphics_image_table{gpu_memory};
- DescriptorTable<TSCEntry> graphics_sampler_table{gpu_memory};
- std::vector<SamplerId> graphics_sampler_ids;
- std::vector<ImageViewId> graphics_image_view_ids;
-
- DescriptorTable<TICEntry> compute_image_table{gpu_memory};
- DescriptorTable<TSCEntry> compute_sampler_table{gpu_memory};
- std::vector<SamplerId> compute_sampler_ids;
- std::vector<ImageViewId> compute_image_view_ids;
+ VideoCore::RasterizerInterface& rasterizer;
+ std::deque<TextureCacheGPUMap> gpu_page_table_storage;
RenderTargets render_targets;
- std::unordered_map<TICEntry, ImageViewId> image_views;
- std::unordered_map<TSCEntry, SamplerId> samplers;
std::unordered_map<RenderTargets, FramebufferId> framebuffers;
- std::unordered_map<u64, std::vector<ImageMapId>, IdentityHash<u64>> page_table;
- std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>> gpu_page_table;
- std::unordered_map<u64, std::vector<ImageId>, IdentityHash<u64>> sparse_page_table;
-
+ std::unordered_map<u64, std::vector<ImageMapId>, Common::IdentityHash<u64>> page_table;
+ std::unordered_map<u64, std::vector<ImageId>, Common::IdentityHash<u64>> sparse_page_table;
std::unordered_map<ImageId, std::vector<ImageViewId>> sparse_views;
VAddr virtual_invalid_space{};
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp
index 1820823b2..1223df5a0 100644
--- a/src/video_core/texture_cache/util.cpp
+++ b/src/video_core/texture_cache/util.cpp
@@ -517,7 +517,6 @@ void SwizzleBlockLinearImage(Tegra::MemoryManager& gpu_memory, GPUVAddr gpu_addr
const u32 host_bytes_per_layer = num_blocks_per_layer * bytes_per_block;
UNIMPLEMENTED_IF(info.tile_width_spacing > 0);
-
UNIMPLEMENTED_IF(copy.image_offset.x != 0);
UNIMPLEMENTED_IF(copy.image_offset.y != 0);
UNIMPLEMENTED_IF(copy.image_offset.z != 0);
@@ -755,7 +754,7 @@ bool IsValidEntry(const Tegra::MemoryManager& gpu_memory, const TICEntry& config
if (address == 0) {
return false;
}
- if (address > (1ULL << 48)) {
+ if (address >= (1ULL << 40)) {
return false;
}
if (gpu_memory.GpuToCpuAddress(address).has_value()) {
diff --git a/src/video_core/textures/astc.cpp b/src/video_core/textures/astc.cpp
index b159494c5..69a32819a 100644
--- a/src/video_core/textures/astc.cpp
+++ b/src/video_core/textures/astc.cpp
@@ -1413,7 +1413,7 @@ static void FillVoidExtentLDR(InputBitStream& strm, std::span<u32> outBuf, u32 b
static void FillError(std::span<u32> outBuf, u32 blockWidth, u32 blockHeight) {
for (u32 j = 0; j < blockHeight; j++) {
for (u32 i = 0; i < blockWidth; i++) {
- outBuf[j * blockWidth + i] = 0xFFFF00FF;
+ outBuf[j * blockWidth + i] = 0x00000000;
}
}
}
@@ -1656,13 +1656,13 @@ void Decompress(std::span<const uint8_t> data, uint32_t width, uint32_t height,
const u32 cols = Common::DivideUp(width, block_width);
Common::ThreadWorker workers{std::max(std::thread::hardware_concurrency(), 2U) / 2,
- "yuzu:ASTCDecompress"};
+ "ASTCDecompress"};
for (u32 z = 0; z < depth; ++z) {
const u32 depth_offset = z * height * width * 4;
for (u32 y_index = 0; y_index < rows; ++y_index) {
- auto decompress_stride = [data, width, height, depth, block_width, block_height, output,
- rows, cols, z, depth_offset, y_index] {
+ auto decompress_stride = [data, width, height, block_width, block_height, output, rows,
+ cols, z, depth_offset, y_index] {
const u32 y = y_index * block_height;
for (u32 x_index = 0; x_index < cols; ++x_index) {
const u32 block_index = (z * rows * cols) + (y_index * cols) + x_index;
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index 913f8ebcb..fd1a4b987 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -21,7 +21,7 @@ constexpr u32 pdep(u32 value) {
u32 m = mask;
for (u32 bit = 1; m; bit += bit) {
if (value & bit)
- result |= m & -m;
+ result |= m & (~m + 1);
m &= m - 1;
}
return result;
@@ -35,7 +35,7 @@ void incrpdep(u32& value) {
template <bool TO_LINEAR, u32 BYTES_PER_PIXEL>
void SwizzleImpl(std::span<u8> output, std::span<const u8> input, u32 width, u32 height, u32 depth,
- u32 block_height, u32 block_depth, u32 stride_alignment) {
+ u32 block_height, u32 block_depth, u32 stride) {
// The origin of the transformation can be configured here, leave it as zero as the current API
// doesn't expose it.
static constexpr u32 origin_x = 0;
@@ -45,7 +45,6 @@ void SwizzleImpl(std::span<u8> output, std::span<const u8> input, u32 width, u32
// We can configure here a custom pitch
// As it's not exposed 'width * BYTES_PER_PIXEL' will be the expected pitch.
const u32 pitch = width * BYTES_PER_PIXEL;
- const u32 stride = Common::AlignUpLog2(width, stride_alignment) * BYTES_PER_PIXEL;
const u32 gobs_in_x = Common::DivCeilLog2(stride, GOB_SIZE_X_SHIFT);
const u32 block_size = gobs_in_x << (GOB_SIZE_SHIFT + block_height + block_depth);
@@ -89,6 +88,69 @@ void SwizzleImpl(std::span<u8> output, std::span<const u8> input, u32 width, u32
}
}
+template <bool TO_LINEAR, u32 BYTES_PER_PIXEL>
+void SwizzleSubrectImpl(std::span<u8> output, std::span<const u8> input, u32 width, u32 height,
+ u32 depth, u32 origin_x, u32 origin_y, u32 extent_x, u32 num_lines,
+ u32 block_height, u32 block_depth, u32 pitch_linear) {
+ // The origin of the transformation can be configured here, leave it as zero as the current API
+ // doesn't expose it.
+ static constexpr u32 origin_z = 0;
+
+ // We can configure here a custom pitch
+ // As it's not exposed 'width * BYTES_PER_PIXEL' will be the expected pitch.
+ const u32 pitch = pitch_linear;
+ const u32 stride = Common::AlignUpLog2(width * BYTES_PER_PIXEL, GOB_SIZE_X_SHIFT);
+
+ const u32 gobs_in_x = Common::DivCeilLog2(stride, GOB_SIZE_X_SHIFT);
+ const u32 block_size = gobs_in_x << (GOB_SIZE_SHIFT + block_height + block_depth);
+ const u32 slice_size =
+ Common::DivCeilLog2(height, block_height + GOB_SIZE_Y_SHIFT) * block_size;
+
+ const u32 block_height_mask = (1U << block_height) - 1;
+ const u32 block_depth_mask = (1U << block_depth) - 1;
+ const u32 x_shift = GOB_SIZE_SHIFT + block_height + block_depth;
+
+ u32 unprocessed_lines = num_lines;
+ u32 extent_y = std::min(num_lines, height - origin_y);
+
+ for (u32 slice = 0; slice < depth; ++slice) {
+ const u32 z = slice + origin_z;
+ const u32 offset_z = (z >> block_depth) * slice_size +
+ ((z & block_depth_mask) << (GOB_SIZE_SHIFT + block_height));
+ const u32 lines_in_y = std::min(unprocessed_lines, extent_y);
+ for (u32 line = 0; line < lines_in_y; ++line) {
+ const u32 y = line + origin_y;
+ const u32 swizzled_y = pdep<SWIZZLE_Y_BITS>(y);
+
+ const u32 block_y = y >> GOB_SIZE_Y_SHIFT;
+ const u32 offset_y = (block_y >> block_height) * block_size +
+ ((block_y & block_height_mask) << GOB_SIZE_SHIFT);
+
+ u32 swizzled_x = pdep<SWIZZLE_X_BITS>(origin_x * BYTES_PER_PIXEL);
+ for (u32 column = 0; column < extent_x;
+ ++column, incrpdep<SWIZZLE_X_BITS, BYTES_PER_PIXEL>(swizzled_x)) {
+ const u32 x = (column + origin_x) * BYTES_PER_PIXEL;
+ const u32 offset_x = (x >> GOB_SIZE_X_SHIFT) << x_shift;
+
+ const u32 base_swizzled_offset = offset_z + offset_y + offset_x;
+ const u32 swizzled_offset = base_swizzled_offset + (swizzled_x | swizzled_y);
+
+ const u32 unswizzled_offset =
+ slice * pitch * height + line * pitch + column * BYTES_PER_PIXEL;
+
+ u8* const dst = &output[TO_LINEAR ? swizzled_offset : unswizzled_offset];
+ const u8* const src = &input[TO_LINEAR ? unswizzled_offset : swizzled_offset];
+
+ std::memcpy(dst, src, BYTES_PER_PIXEL);
+ }
+ }
+ unprocessed_lines -= lines_in_y;
+ if (unprocessed_lines == 0) {
+ return;
+ }
+ }
+}
+
template <bool TO_LINEAR>
void Swizzle(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixel, u32 width,
u32 height, u32 depth, u32 block_height, u32 block_depth, u32 stride_alignment) {
@@ -111,122 +173,39 @@ void Swizzle(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixe
}
}
-template <u32 BYTES_PER_PIXEL>
-void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width,
- u8* swizzled_data, const u8* unswizzled_data, u32 block_height_bit,
- u32 offset_x, u32 offset_y) {
- const u32 block_height = 1U << block_height_bit;
- const u32 image_width_in_gobs =
- (swizzled_width * BYTES_PER_PIXEL + (GOB_SIZE_X - 1)) / GOB_SIZE_X;
- for (u32 line = 0; line < subrect_height; ++line) {
- const u32 dst_y = line + offset_y;
- const u32 gob_address_y =
- (dst_y / (GOB_SIZE_Y * block_height)) * GOB_SIZE * block_height * image_width_in_gobs +
- ((dst_y % (GOB_SIZE_Y * block_height)) / GOB_SIZE_Y) * GOB_SIZE;
-
- const u32 swizzled_y = pdep<SWIZZLE_Y_BITS>(dst_y);
- u32 swizzled_x = pdep<SWIZZLE_X_BITS>(offset_x * BYTES_PER_PIXEL);
- for (u32 x = 0; x < subrect_width;
- ++x, incrpdep<SWIZZLE_X_BITS, BYTES_PER_PIXEL>(swizzled_x)) {
- const u32 dst_x = x + offset_x;
- const u32 gob_address =
- gob_address_y + (dst_x * BYTES_PER_PIXEL / GOB_SIZE_X) * GOB_SIZE * block_height;
- const u32 swizzled_offset = gob_address + (swizzled_x | swizzled_y);
- const u32 unswizzled_offset = line * source_pitch + x * BYTES_PER_PIXEL;
-
- const u8* const source_line = unswizzled_data + unswizzled_offset;
- u8* const dest_addr = swizzled_data + swizzled_offset;
- std::memcpy(dest_addr, source_line, BYTES_PER_PIXEL);
- }
- }
-}
-
-template <u32 BYTES_PER_PIXEL>
-void UnswizzleSubrect(u32 line_length_in, u32 line_count, u32 pitch, u32 width, u32 block_height,
- u32 origin_x, u32 origin_y, u8* output, const u8* input) {
- const u32 stride = width * BYTES_PER_PIXEL;
- const u32 gobs_in_x = (stride + GOB_SIZE_X - 1) / GOB_SIZE_X;
- const u32 block_size = gobs_in_x << (GOB_SIZE_SHIFT + block_height);
-
- const u32 block_height_mask = (1U << block_height) - 1;
- const u32 x_shift = GOB_SIZE_SHIFT + block_height;
-
- for (u32 line = 0; line < line_count; ++line) {
- const u32 src_y = line + origin_y;
- const u32 swizzled_y = pdep<SWIZZLE_Y_BITS>(src_y);
-
- const u32 block_y = src_y >> GOB_SIZE_Y_SHIFT;
- const u32 src_offset_y = (block_y >> block_height) * block_size +
- ((block_y & block_height_mask) << GOB_SIZE_SHIFT);
-
- u32 swizzled_x = pdep<SWIZZLE_X_BITS>(origin_x * BYTES_PER_PIXEL);
- for (u32 column = 0; column < line_length_in;
- ++column, incrpdep<SWIZZLE_X_BITS, BYTES_PER_PIXEL>(swizzled_x)) {
- const u32 src_x = (column + origin_x) * BYTES_PER_PIXEL;
- const u32 src_offset_x = (src_x >> GOB_SIZE_X_SHIFT) << x_shift;
-
- const u32 swizzled_offset = src_offset_y + src_offset_x + (swizzled_x | swizzled_y);
- const u32 unswizzled_offset = line * pitch + column * BYTES_PER_PIXEL;
-
- std::memcpy(output + unswizzled_offset, input + swizzled_offset, BYTES_PER_PIXEL);
- }
- }
-}
-
-template <u32 BYTES_PER_PIXEL>
-void SwizzleSliceToVoxel(u32 line_length_in, u32 line_count, u32 pitch, u32 width, u32 height,
- u32 block_height, u32 block_depth, u32 origin_x, u32 origin_y, u8* output,
- const u8* input) {
- UNIMPLEMENTED_IF(origin_x > 0);
- UNIMPLEMENTED_IF(origin_y > 0);
-
- const u32 stride = width * BYTES_PER_PIXEL;
- const u32 gobs_in_x = (stride + GOB_SIZE_X - 1) / GOB_SIZE_X;
- const u32 block_size = gobs_in_x << (GOB_SIZE_SHIFT + block_height + block_depth);
-
- const u32 block_height_mask = (1U << block_height) - 1;
- const u32 x_shift = static_cast<u32>(GOB_SIZE_SHIFT) + block_height + block_depth;
-
- for (u32 line = 0; line < line_count; ++line) {
- const u32 swizzled_y = pdep<SWIZZLE_Y_BITS>(line);
- const u32 block_y = line / GOB_SIZE_Y;
- const u32 dst_offset_y =
- (block_y >> block_height) * block_size + (block_y & block_height_mask) * GOB_SIZE;
-
- u32 swizzled_x = 0;
- for (u32 x = 0; x < line_length_in; ++x, incrpdep<SWIZZLE_X_BITS, 1>(swizzled_x)) {
- const u32 dst_offset =
- ((x / GOB_SIZE_X) << x_shift) + dst_offset_y + (swizzled_x | swizzled_y);
- const u32 src_offset = x * BYTES_PER_PIXEL + line * pitch;
- std::memcpy(output + dst_offset, input + src_offset, BYTES_PER_PIXEL);
- }
- }
-}
} // Anonymous namespace
void UnswizzleTexture(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixel,
u32 width, u32 height, u32 depth, u32 block_height, u32 block_depth,
u32 stride_alignment) {
+ const u32 stride = Common::AlignUpLog2(width, stride_alignment) * bytes_per_pixel;
+ const u32 new_bpp = std::min(4U, static_cast<u32>(std::countr_zero(width * bytes_per_pixel)));
+ width = (width * bytes_per_pixel) >> new_bpp;
+ bytes_per_pixel = 1U << new_bpp;
Swizzle<false>(output, input, bytes_per_pixel, width, height, depth, block_height, block_depth,
- stride_alignment);
+ stride);
}
void SwizzleTexture(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixel, u32 width,
u32 height, u32 depth, u32 block_height, u32 block_depth,
u32 stride_alignment) {
+ const u32 stride = Common::AlignUpLog2(width, stride_alignment) * bytes_per_pixel;
+ const u32 new_bpp = std::min(4U, static_cast<u32>(std::countr_zero(width * bytes_per_pixel)));
+ width = (width * bytes_per_pixel) >> new_bpp;
+ bytes_per_pixel = 1U << new_bpp;
Swizzle<true>(output, input, bytes_per_pixel, width, height, depth, block_height, block_depth,
- stride_alignment);
+ stride);
}
-void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width,
- u32 bytes_per_pixel, u8* swizzled_data, const u8* unswizzled_data,
- u32 block_height_bit, u32 offset_x, u32 offset_y) {
+void SwizzleSubrect(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixel, u32 width,
+ u32 height, u32 depth, u32 origin_x, u32 origin_y, u32 extent_x, u32 extent_y,
+ u32 block_height, u32 block_depth, u32 pitch_linear) {
switch (bytes_per_pixel) {
#define BPP_CASE(x) \
case x: \
- return SwizzleSubrect<x>(subrect_width, subrect_height, source_pitch, swizzled_width, \
- swizzled_data, unswizzled_data, block_height_bit, offset_x, \
- offset_y);
+ return SwizzleSubrectImpl<true, x>(output, input, width, height, depth, origin_x, \
+ origin_y, extent_x, extent_y, block_height, \
+ block_depth, pitch_linear);
BPP_CASE(1)
BPP_CASE(2)
BPP_CASE(3)
@@ -241,13 +220,15 @@ void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32
}
}
-void UnswizzleSubrect(u32 line_length_in, u32 line_count, u32 pitch, u32 width, u32 bytes_per_pixel,
- u32 block_height, u32 origin_x, u32 origin_y, u8* output, const u8* input) {
+void UnswizzleSubrect(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixel,
+ u32 width, u32 height, u32 depth, u32 origin_x, u32 origin_y, u32 extent_x,
+ u32 extent_y, u32 block_height, u32 block_depth, u32 pitch_linear) {
switch (bytes_per_pixel) {
#define BPP_CASE(x) \
case x: \
- return UnswizzleSubrect<x>(line_length_in, line_count, pitch, width, block_height, \
- origin_x, origin_y, output, input);
+ return SwizzleSubrectImpl<false, x>(output, input, width, height, depth, origin_x, \
+ origin_y, extent_x, extent_y, block_height, \
+ block_depth, pitch_linear);
BPP_CASE(1)
BPP_CASE(2)
BPP_CASE(3)
@@ -262,55 +243,6 @@ void UnswizzleSubrect(u32 line_length_in, u32 line_count, u32 pitch, u32 width,
}
}
-void SwizzleSliceToVoxel(u32 line_length_in, u32 line_count, u32 pitch, u32 width, u32 height,
- u32 bytes_per_pixel, u32 block_height, u32 block_depth, u32 origin_x,
- u32 origin_y, u8* output, const u8* input) {
- switch (bytes_per_pixel) {
-#define BPP_CASE(x) \
- case x: \
- return SwizzleSliceToVoxel<x>(line_length_in, line_count, pitch, width, height, \
- block_height, block_depth, origin_x, origin_y, output, \
- input);
- BPP_CASE(1)
- BPP_CASE(2)
- BPP_CASE(3)
- BPP_CASE(4)
- BPP_CASE(6)
- BPP_CASE(8)
- BPP_CASE(12)
- BPP_CASE(16)
-#undef BPP_CASE
- default:
- ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel);
- }
-}
-
-void SwizzleKepler(const u32 width, const u32 height, const u32 dst_x, const u32 dst_y,
- const u32 block_height_bit, const std::size_t copy_size, const u8* source_data,
- u8* swizzle_data) {
- const u32 block_height = 1U << block_height_bit;
- const u32 image_width_in_gobs{(width + GOB_SIZE_X - 1) / GOB_SIZE_X};
- std::size_t count = 0;
- for (std::size_t y = dst_y; y < height && count < copy_size; ++y) {
- const std::size_t gob_address_y =
- (y / (GOB_SIZE_Y * block_height)) * GOB_SIZE * block_height * image_width_in_gobs +
- ((y % (GOB_SIZE_Y * block_height)) / GOB_SIZE_Y) * GOB_SIZE;
- const u32 swizzled_y = pdep<SWIZZLE_Y_BITS>(static_cast<u32>(y));
- u32 swizzled_x = pdep<SWIZZLE_X_BITS>(dst_x);
- for (std::size_t x = dst_x; x < width && count < copy_size;
- ++x, incrpdep<SWIZZLE_X_BITS, 1>(swizzled_x)) {
- const std::size_t gob_address =
- gob_address_y + (x / GOB_SIZE_X) * GOB_SIZE * block_height;
- const std::size_t swizzled_offset = gob_address + (swizzled_x | swizzled_y);
- const u8* source_line = source_data + count;
- u8* dest_addr = swizzle_data + swizzled_offset;
- count++;
-
- *dest_addr = *source_line;
- }
- }
-}
-
std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
u32 block_height, u32 block_depth) {
if (tiled) {
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h
index 31a11708f..e70407692 100644
--- a/src/video_core/textures/decoders.h
+++ b/src/video_core/textures/decoders.h
@@ -40,7 +40,6 @@ constexpr SwizzleTable MakeSwizzleTable() {
}
return table;
}
-constexpr SwizzleTable SWIZZLE_TABLE = MakeSwizzleTable();
/// Unswizzles a block linear texture into linear memory.
void UnswizzleTexture(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixel,
@@ -57,34 +56,14 @@ std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height
u32 block_height, u32 block_depth);
/// Copies an untiled subrectangle into a tiled surface.
-void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width,
- u32 bytes_per_pixel, u8* swizzled_data, const u8* unswizzled_data,
- u32 block_height_bit, u32 offset_x, u32 offset_y);
+void SwizzleSubrect(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixel, u32 width,
+ u32 height, u32 depth, u32 origin_x, u32 origin_y, u32 extent_x, u32 extent_y,
+ u32 block_height, u32 block_depth, u32 pitch_linear);
/// Copies a tiled subrectangle into a linear surface.
-void UnswizzleSubrect(u32 line_length_in, u32 line_count, u32 pitch, u32 width, u32 bytes_per_pixel,
- u32 block_height, u32 origin_x, u32 origin_y, u8* output, const u8* input);
-
-/// @brief Swizzles a 2D array of pixels into a 3D texture
-/// @param line_length_in Number of pixels per line
-/// @param line_count Number of lines
-/// @param pitch Number of bytes per line
-/// @param width Width of the swizzled texture
-/// @param height Height of the swizzled texture
-/// @param bytes_per_pixel Number of bytes used per pixel
-/// @param block_height Block height shift
-/// @param block_depth Block depth shift
-/// @param origin_x Column offset in pixels of the swizzled texture
-/// @param origin_y Row offset in pixels of the swizzled texture
-/// @param output Pointer to the pixels of the swizzled texture
-/// @param input Pointer to the 2D array of pixels used as input
-/// @pre input and output points to an array large enough to hold the number of bytes used
-void SwizzleSliceToVoxel(u32 line_length_in, u32 line_count, u32 pitch, u32 width, u32 height,
- u32 bytes_per_pixel, u32 block_height, u32 block_depth, u32 origin_x,
- u32 origin_y, u8* output, const u8* input);
-
-void SwizzleKepler(u32 width, u32 height, u32 dst_x, u32 dst_y, u32 block_height,
- std::size_t copy_size, const u8* source_data, u8* swizzle_data);
+void UnswizzleSubrect(std::span<u8> output, std::span<const u8> input, u32 bytes_per_pixel,
+ u32 width, u32 height, u32 depth, u32 origin_x, u32 origin_y, u32 extent_x,
+ u32 extent_y, u32 block_height, u32 block_depth, u32 pitch_linear);
/// Obtains the offset of the gob for positions 'dst_x' & 'dst_y'
u64 GetGOBOffset(u32 width, u32 height, u32 dst_x, u32 dst_y, u32 block_height,
diff --git a/src/video_core/transform_feedback.cpp b/src/video_core/transform_feedback.cpp
index 7e605981c..45071185a 100644
--- a/src/video_core/transform_feedback.cpp
+++ b/src/video_core/transform_feedback.cpp
@@ -15,51 +15,51 @@ namespace VideoCommon {
std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings(
const TransformFeedbackState& state) {
static constexpr std::array VECTORS{
- 28, // gl_Position
- 32, // Generic 0
- 36, // Generic 1
- 40, // Generic 2
- 44, // Generic 3
- 48, // Generic 4
- 52, // Generic 5
- 56, // Generic 6
- 60, // Generic 7
- 64, // Generic 8
- 68, // Generic 9
- 72, // Generic 10
- 76, // Generic 11
- 80, // Generic 12
- 84, // Generic 13
- 88, // Generic 14
- 92, // Generic 15
- 96, // Generic 16
- 100, // Generic 17
- 104, // Generic 18
- 108, // Generic 19
- 112, // Generic 20
- 116, // Generic 21
- 120, // Generic 22
- 124, // Generic 23
- 128, // Generic 24
- 132, // Generic 25
- 136, // Generic 26
- 140, // Generic 27
- 144, // Generic 28
- 148, // Generic 29
- 152, // Generic 30
- 156, // Generic 31
- 160, // gl_FrontColor
- 164, // gl_FrontSecondaryColor
- 160, // gl_BackColor
- 164, // gl_BackSecondaryColor
- 192, // gl_TexCoord[0]
- 196, // gl_TexCoord[1]
- 200, // gl_TexCoord[2]
- 204, // gl_TexCoord[3]
- 208, // gl_TexCoord[4]
- 212, // gl_TexCoord[5]
- 216, // gl_TexCoord[6]
- 220, // gl_TexCoord[7]
+ 28U, // gl_Position
+ 32U, // Generic 0
+ 36U, // Generic 1
+ 40U, // Generic 2
+ 44U, // Generic 3
+ 48U, // Generic 4
+ 52U, // Generic 5
+ 56U, // Generic 6
+ 60U, // Generic 7
+ 64U, // Generic 8
+ 68U, // Generic 9
+ 72U, // Generic 10
+ 76U, // Generic 11
+ 80U, // Generic 12
+ 84U, // Generic 13
+ 88U, // Generic 14
+ 92U, // Generic 15
+ 96U, // Generic 16
+ 100U, // Generic 17
+ 104U, // Generic 18
+ 108U, // Generic 19
+ 112U, // Generic 20
+ 116U, // Generic 21
+ 120U, // Generic 22
+ 124U, // Generic 23
+ 128U, // Generic 24
+ 132U, // Generic 25
+ 136U, // Generic 26
+ 140U, // Generic 27
+ 144U, // Generic 28
+ 148U, // Generic 29
+ 152U, // Generic 30
+ 156U, // Generic 31
+ 160U, // gl_FrontColor
+ 164U, // gl_FrontSecondaryColor
+ 160U, // gl_BackColor
+ 164U, // gl_BackSecondaryColor
+ 192U, // gl_TexCoord[0]
+ 196U, // gl_TexCoord[1]
+ 200U, // gl_TexCoord[2]
+ 204U, // gl_TexCoord[3]
+ 208U, // gl_TexCoord[4]
+ 212U, // gl_TexCoord[5]
+ 216U, // gl_TexCoord[6]
+ 220U, // gl_TexCoord[7]
};
std::vector<Shader::TransformFeedbackVarying> xfb(256);
for (size_t buffer = 0; buffer < state.layouts.size(); ++buffer) {
@@ -68,8 +68,20 @@ std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings(
const u32 varying_count = layout.varying_count;
u32 highest = 0;
for (u32 offset = 0; offset < varying_count; ++offset) {
- const u32 base_offset = offset;
- const u8 location = locations[offset];
+ const auto get_attribute = [&locations](u32 index) -> u32 {
+ switch (index % 4) {
+ case 0:
+ return locations[index / 4].attribute0.Value();
+ case 1:
+ return locations[index / 4].attribute1.Value();
+ case 2:
+ return locations[index / 4].attribute2.Value();
+ case 3:
+ return locations[index / 4].attribute3.Value();
+ }
+ UNREACHABLE();
+ return 0;
+ };
UNIMPLEMENTED_IF_MSG(layout.stream != 0, "Stream is not zero: {}", layout.stream);
Shader::TransformFeedbackVarying varying{
@@ -78,16 +90,18 @@ std::vector<Shader::TransformFeedbackVarying> MakeTransformFeedbackVaryings(
.offset = offset * 4,
.components = 1,
};
- if (std::ranges::find(VECTORS, Common::AlignDown(location, 4)) != VECTORS.end()) {
- UNIMPLEMENTED_IF_MSG(location % 4 != 0, "Unaligned TFB");
+ const u32 base_offset = offset;
+ const auto attribute{get_attribute(offset)};
+ if (std::ranges::find(VECTORS, Common::AlignDown(attribute, 4)) != VECTORS.end()) {
+ UNIMPLEMENTED_IF_MSG(attribute % 4 != 0, "Unaligned TFB {}", attribute);
- const u8 base_index = location / 4;
- while (offset + 1 < varying_count && base_index == locations[offset + 1] / 4) {
+ const auto base_index = attribute / 4;
+ while (offset + 1 < varying_count && base_index == get_attribute(offset + 1) / 4) {
++offset;
++varying.components;
}
}
- xfb[location] = varying;
+ xfb[attribute] = varying;
highest = std::max(highest, (base_offset + varying.components) * 4);
}
UNIMPLEMENTED_IF(highest != layout.stride);
diff --git a/src/video_core/transform_feedback.h b/src/video_core/transform_feedback.h
index a519adb59..d13eb16c3 100644
--- a/src/video_core/transform_feedback.h
+++ b/src/video_core/transform_feedback.h
@@ -19,7 +19,8 @@ struct TransformFeedbackState {
u32 stride;
};
std::array<Layout, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> layouts;
- std::array<std::array<u8, 128>, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers>
+ std::array<std::array<Tegra::Engines::Maxwell3D::Regs::StreamOutLayout, 32>,
+ Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers>
varyings;
};
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h
index 795f16bfb..1b3f493bd 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.h
+++ b/src/video_core/vulkan_common/vulkan_wrapper.h
@@ -519,9 +519,7 @@ public:
dld{rhs.dld} {}
/// Assign an allocation transfering ownership from another allocation.
- /// Releases any previously held allocation.
PoolAllocations& operator=(PoolAllocations&& rhs) noexcept {
- Release();
allocations = std::move(rhs.allocations);
num = rhs.num;
device = rhs.device;
@@ -530,11 +528,6 @@ public:
return *this;
}
- /// Destroys any held allocation.
- ~PoolAllocations() {
- Release();
- }
-
/// Returns the number of allocations.
std::size_t size() const noexcept {
return num;
@@ -557,19 +550,6 @@ public:
}
private:
- /// Destroys the held allocations if they exist.
- void Release() noexcept {
- if (!allocations) {
- return;
- }
- const Span<AllocationType> span(allocations.get(), num);
- const VkResult result = Free(device, pool, span, *dld);
- // There's no way to report errors from a destructor.
- if (result != VK_SUCCESS) {
- std::terminate();
- }
- }
-
std::unique_ptr<AllocationType[]> allocations;
std::size_t num = 0;
VkDevice device = nullptr;
diff --git a/src/web_service/web_backend.cpp b/src/web_service/web_backend.cpp
index 378804c08..12a7e4922 100644
--- a/src/web_service/web_backend.cpp
+++ b/src/web_service/web_backend.cpp
@@ -111,7 +111,8 @@ struct Client::Impl {
httplib::Error error;
if (!cli->send(request, response, error)) {
- LOG_ERROR(WebService, "{} to {} returned null", method, host + path);
+ LOG_ERROR(WebService, "{} to {} returned null (httplib Error: {})", method, host + path,
+ httplib::to_string(error));
return WebResult{WebResult::Code::LibError, "Null response", ""};
}
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp
index 1d8072243..12efdc216 100644
--- a/src/yuzu/applets/qt_controller.cpp
+++ b/src/yuzu/applets/qt_controller.cpp
@@ -291,7 +291,7 @@ bool QtControllerSelectorDialog::CheckIfParametersMet() {
// Here, we check and validate the current configuration against all applicable parameters.
const auto num_connected_players = static_cast<int>(
std::count_if(player_groupboxes.begin(), player_groupboxes.end(),
- [this](const QGroupBox* player) { return player->isChecked(); }));
+ [](const QGroupBox* player) { return player->isChecked(); }));
const auto min_supported_players = parameters.enable_single_mode ? 1 : parameters.min_players;
const auto max_supported_players = parameters.enable_single_mode ? 1 : parameters.max_players;
diff --git a/src/yuzu/applets/qt_controller.ui b/src/yuzu/applets/qt_controller.ui
index c8cb6bcf3..f5eccba70 100644
--- a/src/yuzu/applets/qt_controller.ui
+++ b/src/yuzu/applets/qt_controller.ui
@@ -2300,7 +2300,7 @@
<item>
<widget class="QRadioButton" name="radioUndocked">
<property name="text">
- <string>Undocked</string>
+ <string>Handheld</string>
</property>
</widget>
</item>
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index d3fbdb09d..6acfb7b06 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -47,7 +47,7 @@ EmuThread::EmuThread(Core::System& system_) : system{system_} {}
EmuThread::~EmuThread() = default;
void EmuThread::run() {
- std::string name = "yuzu:EmuControlThread";
+ std::string name = "EmuControlThread";
MicroProfileOnThreadCreate(name.c_str());
Common::SetCurrentThreadName(name.c_str());
@@ -120,8 +120,8 @@ void EmuThread::run() {
}
}
- // Shutdown the core emulation
- system.Shutdown();
+ // Shutdown the main emulated process
+ system.ShutdownMainProcess();
#if MICROPROFILE_ENABLED
MicroProfileOnThreadExit();
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index a4ed68422..927dd1069 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -546,6 +546,7 @@ void Config::ReadDebuggingValues() {
ReadBasicSetting(Settings::values.use_auto_stub);
ReadBasicSetting(Settings::values.enable_all_controllers);
ReadBasicSetting(Settings::values.create_crash_dumps);
+ ReadBasicSetting(Settings::values.perform_vulkan_check);
qt_config->endGroup();
}
@@ -818,6 +819,7 @@ void Config::ReadUIGamelistValues() {
qt_config->beginGroup(QStringLiteral("UIGameList"));
ReadBasicSetting(UISettings::values.show_add_ons);
+ ReadBasicSetting(UISettings::values.show_compat);
ReadBasicSetting(UISettings::values.game_icon_size);
ReadBasicSetting(UISettings::values.folder_icon_size);
ReadBasicSetting(UISettings::values.row_1_text_id);
@@ -1162,6 +1164,7 @@ void Config::SaveDebuggingValues() {
WriteBasicSetting(Settings::values.disable_macro_jit);
WriteBasicSetting(Settings::values.enable_all_controllers);
WriteBasicSetting(Settings::values.create_crash_dumps);
+ WriteBasicSetting(Settings::values.perform_vulkan_check);
qt_config->endGroup();
}
@@ -1412,6 +1415,7 @@ void Config::SaveUIGamelistValues() {
qt_config->beginGroup(QStringLiteral("UIGameList"));
WriteBasicSetting(UISettings::values.show_add_ons);
+ WriteBasicSetting(UISettings::values.show_compat);
WriteBasicSetting(UISettings::values.game_icon_size);
WriteBasicSetting(UISettings::values.folder_icon_size);
WriteBasicSetting(UISettings::values.row_1_text_id);
diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp
index 19b8b15ef..70cc6f84b 100644
--- a/src/yuzu/configuration/configure_audio.cpp
+++ b/src/yuzu/configuration/configure_audio.cpp
@@ -161,8 +161,8 @@ void ConfigureAudio::InitializeAudioSinkComboBox() {
ui->sink_combo_box->clear();
ui->sink_combo_box->addItem(QString::fromUtf8(AudioCore::Sink::auto_device_name));
- for (const char* id : AudioCore::Sink::GetSinkIDs()) {
- ui->sink_combo_box->addItem(QString::fromUtf8(id));
+ for (const auto& id : AudioCore::Sink::GetSinkIDs()) {
+ ui->sink_combo_box->addItem(QString::fromUtf8(id.data(), static_cast<s32>(id.length())));
}
}
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index 622808e94..dacc75a20 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -77,6 +77,7 @@ void ConfigureDebug::SetConfiguration() {
ui->disable_loop_safety_checks->setChecked(
Settings::values.disable_shader_loop_safety_checks.GetValue());
ui->extended_logging->setChecked(Settings::values.extended_logging.GetValue());
+ ui->perform_vulkan_check->setChecked(Settings::values.perform_vulkan_check.GetValue());
#ifdef YUZU_USE_QT_WEB_ENGINE
ui->disable_web_applet->setChecked(UISettings::values.disable_web_applet.GetValue());
@@ -117,6 +118,7 @@ void ConfigureDebug::ApplyConfiguration() {
ui->disable_loop_safety_checks->isChecked();
Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked();
Settings::values.extended_logging = ui->extended_logging->isChecked();
+ Settings::values.perform_vulkan_check = ui->perform_vulkan_check->isChecked();
UISettings::values.disable_web_applet = ui->disable_web_applet->isChecked();
Debugger::ToggleConsole();
Common::Log::Filter filter;
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index 314d47af5..102c8c66c 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -313,6 +313,16 @@
</property>
</widget>
</item>
+ <item row="3" column="0">
+ <widget class="QCheckBox" name="perform_vulkan_check">
+ <property name="toolTip">
+ <string>Enables yuzu to check for a working Vulkan environment when the program starts up. Disable this if this is causing issues with external programs seeing yuzu.</string>
+ </property>
+ <property name="text">
+ <string>Perform Startup Vulkan Check</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 87e5d0f48..bd69d04a6 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -57,9 +57,10 @@ ConfigureGraphics::ConfigureGraphics(const Core::System& system_, QWidget* paren
UpdateBackgroundColorButton(new_bg_color);
});
- ui->api->setEnabled(!UISettings::values.has_broken_vulkan);
- ui->api_widget->setEnabled(!UISettings::values.has_broken_vulkan ||
- Settings::IsConfiguringGlobal());
+ ui->api->setEnabled(!UISettings::values.has_broken_vulkan && ui->api->isEnabled());
+ ui->api_widget->setEnabled(
+ (!UISettings::values.has_broken_vulkan || Settings::IsConfiguringGlobal()) &&
+ ui->api_widget->isEnabled());
ui->bg_label->setVisible(Settings::IsConfiguringGlobal());
ui->bg_combobox->setVisible(!Settings::IsConfiguringGlobal());
}
diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui
index 1e4f74704..fdbb33372 100644
--- a/src/yuzu/configuration/configure_graphics.ui
+++ b/src/yuzu/configuration/configure_graphics.ui
@@ -301,6 +301,11 @@
</item>
<item>
<property name="text">
+ <string>Force 16:10</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
<string>Stretch to Window</string>
</property>
</item>
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index cb55472c9..1db374d4a 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -163,10 +163,9 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
[this, input_subsystem, &hid_core] {
CallConfigureDialog<ConfigureRingController>(*this, input_subsystem, hid_core);
});
- connect(advanced, &ConfigureInputAdvanced::CallCameraDialog,
- [this, input_subsystem, &hid_core] {
- CallConfigureDialog<ConfigureCamera>(*this, input_subsystem);
- });
+ connect(advanced, &ConfigureInputAdvanced::CallCameraDialog, [this, input_subsystem] {
+ CallConfigureDialog<ConfigureCamera>(*this, input_subsystem);
+ });
connect(ui->vibrationButton, &QPushButton::clicked,
[this, &hid_core] { CallConfigureDialog<ConfigureVibration>(*this, hid_core); });
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp
index 48f71b53c..92e6da6ee 100644
--- a/src/yuzu/configuration/configure_ui.cpp
+++ b/src/yuzu/configuration/configure_ui.cpp
@@ -72,6 +72,7 @@ ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent)
// Force game list reload if any of the relevant settings are changed.
connect(ui->show_add_ons, &QCheckBox::stateChanged, this, &ConfigureUi::RequestGameListUpdate);
+ connect(ui->show_compat, &QCheckBox::stateChanged, this, &ConfigureUi::RequestGameListUpdate);
connect(ui->game_icon_size_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&ConfigureUi::RequestGameListUpdate);
connect(ui->folder_icon_size_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged),
@@ -109,6 +110,7 @@ void ConfigureUi::ApplyConfiguration() {
UISettings::values.theme =
ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString();
UISettings::values.show_add_ons = ui->show_add_ons->isChecked();
+ UISettings::values.show_compat = ui->show_compat->isChecked();
UISettings::values.game_icon_size = ui->game_icon_size_combobox->currentData().toUInt();
UISettings::values.folder_icon_size = ui->folder_icon_size_combobox->currentData().toUInt();
UISettings::values.row_1_text_id = ui->row_1_text_combobox->currentData().toUInt();
@@ -129,6 +131,7 @@ void ConfigureUi::SetConfiguration() {
ui->language_combobox->setCurrentIndex(
ui->language_combobox->findData(UISettings::values.language));
ui->show_add_ons->setChecked(UISettings::values.show_add_ons.GetValue());
+ ui->show_compat->setChecked(UISettings::values.show_compat.GetValue());
ui->game_icon_size_combobox->setCurrentIndex(
ui->game_icon_size_combobox->findData(UISettings::values.game_icon_size.GetValue()));
ui->folder_icon_size_combobox->setCurrentIndex(
diff --git a/src/yuzu/configuration/configure_ui.ui b/src/yuzu/configuration/configure_ui.ui
index a50df7f6f..f0b719ba3 100644
--- a/src/yuzu/configuration/configure_ui.ui
+++ b/src/yuzu/configuration/configure_ui.ui
@@ -77,6 +77,13 @@
<item>
<layout class="QVBoxLayout" name="GeneralVerticalLayout">
<item>
+ <widget class="QCheckBox" name="show_compat">
+ <property name="text">
+ <string>Show Compatibility List</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QCheckBox" name="show_add_ons">
<property name="text">
<string>Show Add-Ons Column</string>
diff --git a/src/yuzu/configuration/input_profiles.cpp b/src/yuzu/configuration/input_profiles.cpp
index 807afbeb2..9bb69cab1 100644
--- a/src/yuzu/configuration/input_profiles.cpp
+++ b/src/yuzu/configuration/input_profiles.cpp
@@ -67,6 +67,8 @@ std::vector<std::string> InputProfiles::GetInputProfileNames() {
profile_names.push_back(profile_name);
}
+ std::stable_sort(profile_names.begin(), profile_names.end());
+
return profile_names;
}
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index b127badc2..d6adfca16 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -335,6 +335,7 @@ GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvid
RetranslateUI();
tree_view->setColumnHidden(COLUMN_ADD_ONS, !UISettings::values.show_add_ons);
+ tree_view->setColumnHidden(COLUMN_COMPATIBILITY, !UISettings::values.show_compat);
item_model->setSortRole(GameListItemPath::SortRole);
connect(main_window, &GMainWindow::UpdateThemedIcons, this, &GameList::OnUpdateThemedIcons);
@@ -786,6 +787,7 @@ void GameList::PopulateAsync(QVector<UISettings::GameDir>& game_dirs) {
// Update the columns in case UISettings has changed
tree_view->setColumnHidden(COLUMN_ADD_ONS, !UISettings::values.show_add_ons);
+ tree_view->setColumnHidden(COLUMN_COMPATIBILITY, !UISettings::values.show_compat);
// Delete any rows that might already exist if we're repopulating
item_model->removeRows(0, item_model->rowCount());
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 3c1bd19db..7b16d7f7e 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -3,6 +3,7 @@
#include <cinttypes>
#include <clocale>
+#include <cmath>
#include <memory>
#include <thread>
#ifdef __APPLE__
@@ -105,12 +106,12 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "core/hle/kernel/k_process.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/filesystem/filesystem.h"
-#include "core/hle/service/nfp/nfp.h"
#include "core/hle/service/sm/sm.h"
#include "core/loader/loader.h"
#include "core/perf_stats.h"
#include "core/telemetry_session.h"
#include "input_common/drivers/tas_input.h"
+#include "input_common/drivers/virtual_amiibo.h"
#include "input_common/main.h"
#include "ui_main.h"
#include "util/overlay_dialog.h"
@@ -261,6 +262,18 @@ static QString PrettyProductName() {
return QSysInfo::prettyProductName();
}
+#ifdef _WIN32
+static void OverrideWindowsFont() {
+ // Qt5 chooses these fonts on Windows and they have fairly ugly alphanumeric/cyrllic characters
+ // Asking to use "MS Shell Dlg 2" gives better other chars while leaving the Chinese Characters.
+ const QString startup_font = QApplication::font().family();
+ const QStringList ugly_fonts = {QStringLiteral("SimSun"), QStringLiteral("PMingLiU")};
+ if (ugly_fonts.contains(startup_font)) {
+ QApplication::setFont(QFont(QStringLiteral("MS Shell Dlg 2"), 9, QFont::Normal));
+ }
+}
+#endif
+
bool GMainWindow::CheckDarkMode() {
#ifdef __linux__
const QPalette test_palette(qApp->palette());
@@ -281,6 +294,7 @@ GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan
#ifdef __linux__
SetupSigInterrupts();
#endif
+ system->Initialize();
Common::Log::Initialize();
LoadTranslation();
@@ -899,8 +913,8 @@ void GMainWindow::InitializeWidgets() {
}
// TODO (flTobi): Add the widget when multiplayer is fully implemented
- // statusBar()->addPermanentWidget(multiplayer_state->GetStatusText(), 0);
- // statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon(), 0);
+ statusBar()->addPermanentWidget(multiplayer_state->GetStatusText(), 0);
+ statusBar()->addPermanentWidget(multiplayer_state->GetStatusIcon(), 0);
tas_label = new QLabel();
tas_label->setObjectName(QStringLiteral("TASlabel"));
@@ -1299,6 +1313,7 @@ void GMainWindow::ConnectMenuEvents() {
&MultiplayerState::OnDirectConnectToRoom);
connect(ui->action_Show_Room, &QAction::triggered, multiplayer_state,
&MultiplayerState::OnOpenNetworkRoom);
+ connect(multiplayer_state, &MultiplayerState::SaveConfig, this, &GMainWindow::OnSaveConfig);
// Tools
connect_menu(ui->action_Rederive, std::bind(&GMainWindow::OnReinitializeKeys, this,
@@ -1339,6 +1354,8 @@ void GMainWindow::UpdateMenuState() {
} else {
ui->action_Pause->setText(tr("&Pause"));
}
+
+ multiplayer_state->UpdateNotificationStatus();
}
void GMainWindow::OnDisplayTitleBars(bool show) {
@@ -1879,6 +1896,8 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
case GameListOpenTarget::SaveData: {
open_target = tr("Save Data");
const auto nand_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir);
+ auto vfs_nand_dir =
+ vfs->OpenDirectory(Common::FS::PathToUTF8String(nand_dir), FileSys::Mode::Read);
if (has_user_save) {
// User save data
@@ -1905,15 +1924,15 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
ASSERT(user_id);
const auto user_save_data_path = FileSys::SaveDataFactory::GetFullPath(
- *system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData,
- program_id, user_id->AsU128(), 0);
+ *system, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser,
+ FileSys::SaveDataType::SaveData, program_id, user_id->AsU128(), 0);
path = Common::FS::ConcatPathSafe(nand_dir, user_save_data_path);
} else {
// Device save data
const auto device_save_data_path = FileSys::SaveDataFactory::GetFullPath(
- *system, FileSys::SaveDataSpaceId::NandUser, FileSys::SaveDataType::SaveData,
- program_id, {}, 0);
+ *system, vfs_nand_dir, FileSys::SaveDataSpaceId::NandUser,
+ FileSys::SaveDataType::SaveData, program_id, {}, 0);
path = Common::FS::ConcatPathSafe(nand_dir, device_save_data_path);
}
@@ -2000,7 +2019,7 @@ static bool RomFSRawCopy(QProgressDialog& dialog, const FileSys::VirtualDir& src
}
void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type) {
- const QString entry_type = [this, type] {
+ const QString entry_type = [type] {
switch (type) {
case InstalledEntryType::Game:
return tr("Contents");
@@ -2097,7 +2116,7 @@ void GMainWindow::RemoveAddOnContent(u64 program_id, const QString& entry_type)
void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target,
const std::string& game_path) {
- const QString question = [this, target] {
+ const QString question = [target] {
switch (target) {
case GameListRemoveTarget::GlShaderCache:
return tr("Delete OpenGL Transferable Shader Cache?");
@@ -2770,6 +2789,11 @@ void GMainWindow::OnExit() {
OnStopGame();
}
+void GMainWindow::OnSaveConfig() {
+ system->ApplySettings();
+ config->Save();
+}
+
void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) {
OverlayDialog dialog(render_window, *system, error_code, error_text, QString{}, tr("OK"),
Qt::AlignLeft | Qt::AlignVCenter);
@@ -3211,21 +3235,16 @@ void GMainWindow::OnLoadAmiibo() {
return;
}
- Service::SM::ServiceManager& sm = system->ServiceManager();
- auto nfc = sm.GetService<Service::NFP::Module::Interface>("nfp:user");
- if (nfc == nullptr) {
- QMessageBox::warning(this, tr("Error"), tr("The current game is not looking for amiibos"));
- return;
- }
- const auto nfc_state = nfc->GetCurrentState();
- if (nfc_state == Service::NFP::DeviceState::TagFound ||
- nfc_state == Service::NFP::DeviceState::TagMounted) {
- nfc->CloseAmiibo();
+ auto* virtual_amiibo = input_subsystem->GetVirtualAmiibo();
+
+ // Remove amiibo if one is connected
+ if (virtual_amiibo->GetCurrentState() == InputCommon::VirtualAmiibo::State::AmiiboIsOpen) {
+ virtual_amiibo->CloseAmiibo();
QMessageBox::warning(this, tr("Amiibo"), tr("The current amiibo has been removed"));
return;
}
- if (nfc_state != Service::NFP::DeviceState::SearchingForTag) {
+ if (virtual_amiibo->GetCurrentState() != InputCommon::VirtualAmiibo::State::WaitingForAmiibo) {
QMessageBox::warning(this, tr("Error"), tr("The current game is not looking for amiibos"));
return;
}
@@ -3244,24 +3263,30 @@ void GMainWindow::OnLoadAmiibo() {
}
void GMainWindow::LoadAmiibo(const QString& filename) {
- Service::SM::ServiceManager& sm = system->ServiceManager();
- auto nfc = sm.GetService<Service::NFP::Module::Interface>("nfp:user");
- if (nfc == nullptr) {
- return;
- }
-
+ auto* virtual_amiibo = input_subsystem->GetVirtualAmiibo();
+ const QString title = tr("Error loading Amiibo data");
// Remove amiibo if one is connected
- const auto nfc_state = nfc->GetCurrentState();
- if (nfc_state == Service::NFP::DeviceState::TagFound ||
- nfc_state == Service::NFP::DeviceState::TagMounted) {
- nfc->CloseAmiibo();
+ if (virtual_amiibo->GetCurrentState() == InputCommon::VirtualAmiibo::State::AmiiboIsOpen) {
+ virtual_amiibo->CloseAmiibo();
QMessageBox::warning(this, tr("Amiibo"), tr("The current amiibo has been removed"));
return;
}
- if (!nfc->LoadAmiibo(filename.toStdString())) {
- QMessageBox::warning(this, tr("Error loading Amiibo data"),
- tr("Unable to load Amiibo data."));
+ switch (virtual_amiibo->LoadAmiibo(filename.toStdString())) {
+ case InputCommon::VirtualAmiibo::Info::NotAnAmiibo:
+ QMessageBox::warning(this, title, tr("The selected file is not a valid amiibo"));
+ break;
+ case InputCommon::VirtualAmiibo::Info::UnableToLoad:
+ QMessageBox::warning(this, title, tr("The selected file is already on use"));
+ break;
+ case InputCommon::VirtualAmiibo::Info::WrongDeviceState:
+ QMessageBox::warning(this, title, tr("The current game is not looking for amiibos"));
+ break;
+ case InputCommon::VirtualAmiibo::Info::Unknown:
+ QMessageBox::warning(this, title, tr("An unknown error occurred"));
+ break;
+ default:
+ break;
}
}
@@ -3442,9 +3467,10 @@ void GMainWindow::UpdateStatusBar() {
}
if (!Settings::values.use_speed_limit) {
game_fps_label->setText(
- tr("Game: %1 FPS (Unlocked)").arg(results.average_game_fps, 0, 'f', 0));
+ tr("Game: %1 FPS (Unlocked)").arg(std::round(results.average_game_fps), 0, 'f', 0));
} else {
- game_fps_label->setText(tr("Game: %1 FPS").arg(results.average_game_fps, 0, 'f', 0));
+ game_fps_label->setText(
+ tr("Game: %1 FPS").arg(std::round(results.average_game_fps), 0, 'f', 0));
}
emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2));
@@ -4086,7 +4112,8 @@ int main(int argc, char* argv[]) {
}
#endif
- if (StartupChecks(argv[0], &has_broken_vulkan)) {
+ if (StartupChecks(argv[0], &has_broken_vulkan,
+ Settings::values.perform_vulkan_check.GetValue())) {
return 0;
}
@@ -4125,6 +4152,10 @@ int main(int argc, char* argv[]) {
QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
QApplication app(argc, argv);
+#ifdef _WIN32
+ OverrideWindowsFont();
+#endif
+
// Workaround for QTBUG-85409, for Suzhou numerals the number 1 is actually \u3021
// so we can see if we get \u3008 instead
// TL;DR all other number formats are consecutive in unicode code points
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 716aef063..f7aa8e417 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -169,6 +169,7 @@ public slots:
void OnLoadComplete();
void OnExecuteProgram(std::size_t program_index);
void OnExit();
+ void OnSaveConfig();
void ControllerSelectorReconfigureControllers(
const Core::Frontend::ControllerParameters& parameters);
void SoftwareKeyboardInitialize(
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui
index cdf31b417..e670acc30 100644
--- a/src/yuzu/main.ui
+++ b/src/yuzu/main.ui
@@ -55,7 +55,6 @@
<addaction name="separator"/>
<addaction name="menu_recent_files"/>
<addaction name="separator"/>
- <addaction name="separator"/>
<addaction name="action_Load_Amiibo"/>
<addaction name="separator"/>
<addaction name="action_Open_yuzu_Folder"/>
@@ -120,6 +119,20 @@
<addaction name="menu_Reset_Window_Size"/>
<addaction name="menu_View_Debugging"/>
</widget>
+ <widget class="QMenu" name="menu_Multiplayer">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="title">
+ <string>&amp;Multiplayer</string>
+ </property>
+ <addaction name="action_View_Lobby"/>
+ <addaction name="action_Start_Room"/>
+ <addaction name="action_Connect_To_Room"/>
+ <addaction name="separator"/>
+ <addaction name="action_Show_Room"/>
+ <addaction name="action_Leave_Room"/>
+ </widget>
<widget class="QMenu" name="menu_Tools">
<property name="title">
<string>&amp;Tools</string>
@@ -251,7 +264,7 @@
<bool>true</bool>
</property>
<property name="text">
- <string>Browse Public Game Lobby</string>
+ <string>&amp;Browse Public Game Lobby</string>
</property>
</action>
<action name="action_Start_Room">
@@ -259,7 +272,7 @@
<bool>true</bool>
</property>
<property name="text">
- <string>Create Room</string>
+ <string>&amp;Create Room</string>
</property>
</action>
<action name="action_Leave_Room">
@@ -267,12 +280,12 @@
<bool>false</bool>
</property>
<property name="text">
- <string>Leave Room</string>
+ <string>&amp;Leave Room</string>
</property>
</action>
<action name="action_Connect_To_Room">
<property name="text">
- <string>Direct Connect to Room</string>
+ <string>&amp;Direct Connect to Room</string>
</property>
</action>
<action name="action_Show_Room">
@@ -280,7 +293,7 @@
<bool>false</bool>
</property>
<property name="text">
- <string>Show Current Room</string>
+ <string>&amp;Show Current Room</string>
</property>
</action>
<action name="action_Fullscreen">
diff --git a/src/yuzu/multiplayer/chat_room.cpp b/src/yuzu/multiplayer/chat_room.cpp
index 9e672f82e..dec9696c1 100644
--- a/src/yuzu/multiplayer/chat_room.cpp
+++ b/src/yuzu/multiplayer/chat_room.cpp
@@ -61,7 +61,10 @@ public:
/// Format the message using the players color
QString GetPlayerChatMessage(u16 player) const {
- auto color = player_color[player % 16];
+ const bool is_dark_theme = QIcon::themeName().contains(QStringLiteral("dark")) ||
+ QIcon::themeName().contains(QStringLiteral("midnight"));
+ auto color =
+ is_dark_theme ? player_color_dark[player % 16] : player_color_default[player % 16];
QString name;
if (username.isEmpty() || username == nickname) {
name = nickname;
@@ -84,9 +87,12 @@ public:
}
private:
- static constexpr std::array<const char*, 16> player_color = {
+ static constexpr std::array<const char*, 16> player_color_default = {
{"#0000FF", "#FF0000", "#8A2BE2", "#FF69B4", "#1E90FF", "#008000", "#00FF7F", "#B22222",
- "#DAA520", "#FF4500", "#2E8B57", "#5F9EA0", "#D2691E", "#9ACD32", "#FF7F50", "FFFF00"}};
+ "#DAA520", "#FF4500", "#2E8B57", "#5F9EA0", "#D2691E", "#9ACD32", "#FF7F50", "#FFFF00"}};
+ static constexpr std::array<const char*, 16> player_color_dark = {
+ {"#559AD1", "#4EC9A8", "#D69D85", "#C6C923", "#B975B5", "#D81F1F", "#7EAE39", "#4F8733",
+ "#F7CD8A", "#6FCACF", "#CE4897", "#8A2BE2", "#D2691E", "#9ACD32", "#FF7F50", "#152ccd"}};
static constexpr char ping_color[] = "#FFFF00";
QString timestamp;
diff --git a/src/yuzu/multiplayer/client_room.cpp b/src/yuzu/multiplayer/client_room.cpp
index b34a8d004..caf34a414 100644
--- a/src/yuzu/multiplayer/client_room.cpp
+++ b/src/yuzu/multiplayer/client_room.cpp
@@ -97,8 +97,9 @@ void ClientRoomWindow::UpdateView() {
auto memberlist = member->GetMemberInformation();
ui->chat->SetPlayerList(memberlist);
const auto information = member->GetRoomInformation();
- setWindowTitle(QString(tr("%1 (%2/%3 members) - connected"))
+ setWindowTitle(QString(tr("%1 - %2 (%3/%4 members) - connected"))
.arg(QString::fromStdString(information.name))
+ .arg(QString::fromStdString(information.preferred_game.name))
.arg(memberlist.size())
.arg(information.member_slots));
ui->description->setText(QString::fromStdString(information.description));
diff --git a/src/yuzu/multiplayer/direct_connect.cpp b/src/yuzu/multiplayer/direct_connect.cpp
index 017063074..10bf0a4fb 100644
--- a/src/yuzu/multiplayer/direct_connect.cpp
+++ b/src/yuzu/multiplayer/direct_connect.cpp
@@ -106,6 +106,8 @@ void DirectConnectWindow::Connect() {
UISettings::values.multiplayer_port = UISettings::values.multiplayer_port.GetDefault();
}
+ emit SaveConfig();
+
// attempt to connect in a different thread
QFuture<void> f = QtConcurrent::run([&] {
if (auto room_member = room_network.GetRoomMember().lock()) {
diff --git a/src/yuzu/multiplayer/direct_connect.h b/src/yuzu/multiplayer/direct_connect.h
index e39dd1e0d..b8f66cfb2 100644
--- a/src/yuzu/multiplayer/direct_connect.h
+++ b/src/yuzu/multiplayer/direct_connect.h
@@ -31,6 +31,7 @@ signals:
* connections that it might have.
*/
void Closed();
+ void SaveConfig();
private slots:
void OnConnection();
diff --git a/src/yuzu/multiplayer/host_room.cpp b/src/yuzu/multiplayer/host_room.cpp
index 0c6adfd04..a8faa5b24 100644
--- a/src/yuzu/multiplayer/host_room.cpp
+++ b/src/yuzu/multiplayer/host_room.cpp
@@ -232,6 +232,7 @@ void HostRoomWindow::Host() {
}
UISettings::values.multiplayer_room_description = ui->room_description->toPlainText();
ui->host->setEnabled(true);
+ emit SaveConfig();
close();
}
}
diff --git a/src/yuzu/multiplayer/host_room.h b/src/yuzu/multiplayer/host_room.h
index 034cb2eef..ae816e2e0 100644
--- a/src/yuzu/multiplayer/host_room.h
+++ b/src/yuzu/multiplayer/host_room.h
@@ -46,6 +46,9 @@ public:
void UpdateGameList(QStandardItemModel* list);
void RetranslateUi();
+signals:
+ void SaveConfig();
+
private:
void Host();
std::unique_ptr<Network::VerifyUser::Backend> CreateVerifyBackend(bool use_validation) const;
diff --git a/src/yuzu/multiplayer/lobby.cpp b/src/yuzu/multiplayer/lobby.cpp
index 107d40547..08c275696 100644
--- a/src/yuzu/multiplayer/lobby.cpp
+++ b/src/yuzu/multiplayer/lobby.cpp
@@ -7,6 +7,7 @@
#include "common/logging/log.h"
#include "common/settings.h"
#include "core/core.h"
+#include "core/hle/service/acc/profile_manager.h"
#include "core/internal_network/network_interface.h"
#include "network/network.h"
#include "ui_lobby.h"
@@ -26,9 +27,9 @@
Lobby::Lobby(QWidget* parent, QStandardItemModel* list,
std::shared_ptr<Core::AnnounceMultiplayerSession> session, Core::System& system_)
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint),
- ui(std::make_unique<Ui::Lobby>()),
- announce_multiplayer_session(session), system{system_}, room_network{
- system.GetRoomNetwork()} {
+ ui(std::make_unique<Ui::Lobby>()), announce_multiplayer_session(session),
+ profile_manager(std::make_unique<Service::Account::ProfileManager>()), system{system_},
+ room_network{system.GetRoomNetwork()} {
ui->setupUi(this);
// setup the watcher for background connections
@@ -60,9 +61,17 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list,
ui->nickname->setValidator(validation.GetNickname());
ui->nickname->setText(UISettings::values.multiplayer_nickname.GetValue());
- if (ui->nickname->text().isEmpty() && !Settings::values.yuzu_username.GetValue().empty()) {
- // Use yuzu Web Service user name as nickname by default
- ui->nickname->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
+
+ // Try find the best nickname by default
+ if (ui->nickname->text().isEmpty() || ui->nickname->text() == QStringLiteral("yuzu")) {
+ if (!Settings::values.yuzu_username.GetValue().empty()) {
+ ui->nickname->setText(
+ QString::fromStdString(Settings::values.yuzu_username.GetValue()));
+ } else if (!GetProfileUsername().empty()) {
+ ui->nickname->setText(QString::fromStdString(GetProfileUsername()));
+ } else {
+ ui->nickname->setText(QStringLiteral("yuzu"));
+ }
}
// UI Buttons
@@ -76,12 +85,6 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list,
// Actions
connect(&room_list_watcher, &QFutureWatcher<AnnounceMultiplayerRoom::RoomList>::finished, this,
&Lobby::OnRefreshLobby);
-
- // manually start a refresh when the window is opening
- // TODO(jroweboy): if this refresh is slow for people with bad internet, then don't do it as
- // part of the constructor, but offload the refresh until after the window shown. perhaps emit a
- // refreshroomlist signal from places that open the lobby
- RefreshLobby();
}
Lobby::~Lobby() = default;
@@ -96,6 +99,7 @@ void Lobby::UpdateGameList(QStandardItemModel* list) {
}
if (proxy)
proxy->UpdateGameList(game_list);
+ ui->room_list->sortByColumn(Column::GAME_NAME, Qt::AscendingOrder);
}
void Lobby::RetranslateUi() {
@@ -117,6 +121,11 @@ void Lobby::OnExpandRoom(const QModelIndex& index) {
void Lobby::OnJoinRoom(const QModelIndex& source) {
if (!Network::GetSelectedNetworkInterface()) {
+ LOG_INFO(WebService, "Automatically selected network interface for room network.");
+ Network::SelectFirstNetworkInterface();
+ }
+
+ if (!Network::GetSelectedNetworkInterface()) {
NetworkMessage::ErrorManager::ShowError(
NetworkMessage::ErrorManager::NO_INTERFACE_SELECTED);
return;
@@ -197,16 +206,16 @@ void Lobby::OnJoinRoom(const QModelIndex& source) {
proxy->data(connection_index, LobbyItemHost::HostIPRole).toString();
UISettings::values.multiplayer_port =
proxy->data(connection_index, LobbyItemHost::HostPortRole).toInt();
+ emit SaveConfig();
}
void Lobby::ResetModel() {
model->clear();
model->insertColumns(0, Column::TOTAL);
- model->setHeaderData(Column::EXPAND, Qt::Horizontal, QString(), Qt::DisplayRole);
+ model->setHeaderData(Column::MEMBER, Qt::Horizontal, tr("Players"), Qt::DisplayRole);
model->setHeaderData(Column::ROOM_NAME, Qt::Horizontal, tr("Room Name"), Qt::DisplayRole);
model->setHeaderData(Column::GAME_NAME, Qt::Horizontal, tr("Preferred Game"), Qt::DisplayRole);
model->setHeaderData(Column::HOST, Qt::Horizontal, tr("Host"), Qt::DisplayRole);
- model->setHeaderData(Column::MEMBER, Qt::Horizontal, tr("Players"), Qt::DisplayRole);
}
void Lobby::RefreshLobby() {
@@ -229,6 +238,7 @@ void Lobby::OnRefreshLobby() {
for (int r = 0; r < game_list->rowCount(); ++r) {
auto index = game_list->index(r, 0);
auto game_id = game_list->data(index, GameListItemPath::ProgramIdRole).toULongLong();
+
if (game_id != 0 && room.information.preferred_game.id == game_id) {
smdh_icon = game_list->data(index, Qt::DecorationRole).value<QPixmap>();
}
@@ -243,17 +253,16 @@ void Lobby::OnRefreshLobby() {
members.append(var);
}
- auto first_item = new LobbyItem();
+ auto first_item = new LobbyItemGame(
+ room.information.preferred_game.id,
+ QString::fromStdString(room.information.preferred_game.name), smdh_icon);
auto row = QList<QStandardItem*>({
first_item,
new LobbyItemName(room.has_password, QString::fromStdString(room.information.name)),
- new LobbyItemGame(room.information.preferred_game.id,
- QString::fromStdString(room.information.preferred_game.name),
- smdh_icon),
+ new LobbyItemMemberList(members, room.information.member_slots),
new LobbyItemHost(QString::fromStdString(room.information.host_username),
QString::fromStdString(room.ip), room.information.port,
QString::fromStdString(room.verify_uid)),
- new LobbyItemMemberList(members, room.information.member_slots),
});
model->appendRow(row);
// To make the rows expandable, add the member data as a child of the first column of the
@@ -283,6 +292,26 @@ void Lobby::OnRefreshLobby() {
ui->room_list->setFirstColumnSpanned(j, proxy->index(i, 0), true);
}
}
+
+ ui->room_list->sortByColumn(Column::GAME_NAME, Qt::AscendingOrder);
+}
+
+std::string Lobby::GetProfileUsername() {
+ const auto& current_user = profile_manager->GetUser(Settings::values.current_user.GetValue());
+ Service::Account::ProfileBase profile{};
+
+ if (!current_user.has_value()) {
+ return "";
+ }
+
+ if (!profile_manager->GetProfileBase(*current_user, profile)) {
+ return "";
+ }
+
+ const auto text = Common::StringFromFixedZeroTerminatedBuffer(
+ reinterpret_cast<const char*>(profile.username.data()), profile.username.size());
+
+ return text;
}
LobbyFilterProxyModel::LobbyFilterProxyModel(QWidget* parent, QStandardItemModel* list)
diff --git a/src/yuzu/multiplayer/lobby.h b/src/yuzu/multiplayer/lobby.h
index 2696aec21..300dad13e 100644
--- a/src/yuzu/multiplayer/lobby.h
+++ b/src/yuzu/multiplayer/lobby.h
@@ -24,6 +24,10 @@ namespace Core {
class System;
}
+namespace Service::Account {
+class ProfileManager;
+}
+
/**
* Listing of all public games pulled from services. The lobby should be simple enough for users to
* find the game they want to play, and join it.
@@ -75,8 +79,11 @@ private slots:
signals:
void StateChanged(const Network::RoomMember::State&);
+ void SaveConfig();
private:
+ std::string GetProfileUsername();
+
/**
* Removes all entries in the Lobby before refreshing.
*/
@@ -96,6 +103,7 @@ private:
QFutureWatcher<AnnounceMultiplayerRoom::RoomList> room_list_watcher;
std::weak_ptr<Core::AnnounceMultiplayerSession> announce_multiplayer_session;
+ std::unique_ptr<Service::Account::ProfileManager> profile_manager;
QFutureWatcher<void>* watcher;
Validation validation;
Core::System& system;
diff --git a/src/yuzu/multiplayer/lobby_p.h b/src/yuzu/multiplayer/lobby_p.h
index 8071cede4..068c95aca 100644
--- a/src/yuzu/multiplayer/lobby_p.h
+++ b/src/yuzu/multiplayer/lobby_p.h
@@ -11,11 +11,10 @@
namespace Column {
enum List {
- EXPAND,
- ROOM_NAME,
GAME_NAME,
- HOST,
+ ROOM_NAME,
MEMBER,
+ HOST,
TOTAL,
};
}
@@ -91,6 +90,8 @@ public:
setData(game_name, GameNameRole);
if (!smdh_icon.isNull()) {
setData(smdh_icon, GameIconRole);
+ } else {
+ setData(QIcon::fromTheme(QStringLiteral("chip")).pixmap(32), GameIconRole);
}
}
@@ -98,7 +99,12 @@ public:
if (role == Qt::DecorationRole) {
auto val = data(GameIconRole);
if (val.isValid()) {
- val = val.value<QPixmap>().scaled(16, 16, Qt::KeepAspectRatio);
+ val = val.value<QPixmap>().scaled(32, 32, Qt::KeepAspectRatio,
+ Qt::TransformationMode::SmoothTransformation);
+ } else {
+ auto blank_image = QPixmap(32, 32);
+ blank_image.fill(Qt::black);
+ val = blank_image;
}
return val;
} else if (role != Qt::DisplayRole) {
@@ -191,8 +197,8 @@ public:
return LobbyItem::data(role);
}
auto members = data(MemberListRole).toList();
- return QStringLiteral("%1 / %2").arg(QString::number(members.size()),
- data(MaxPlayerRole).toString());
+ return QStringLiteral("%1 / %2 ")
+ .arg(QString::number(members.size()), data(MaxPlayerRole).toString());
}
bool operator<(const QStandardItem& other) const override {
diff --git a/src/yuzu/multiplayer/message.cpp b/src/yuzu/multiplayer/message.cpp
index 758b5b731..6d8f18274 100644
--- a/src/yuzu/multiplayer/message.cpp
+++ b/src/yuzu/multiplayer/message.cpp
@@ -49,9 +49,9 @@ const ConnectionError ErrorManager::PERMISSION_DENIED(
QT_TR_NOOP("You do not have enough permission to perform this action."));
const ConnectionError ErrorManager::NO_SUCH_USER(QT_TR_NOOP(
"The user you are trying to kick/ban could not be found.\nThey may have left the room."));
-const ConnectionError ErrorManager::NO_INTERFACE_SELECTED(
- QT_TR_NOOP("No network interface is selected.\nPlease go to Configure -> System -> Network and "
- "make a selection."));
+const ConnectionError ErrorManager::NO_INTERFACE_SELECTED(QT_TR_NOOP(
+ "No valid network interface is selected.\nPlease go to Configure -> System -> Network and "
+ "make a selection."));
static bool WarnMessage(const std::string& title, const std::string& text) {
return QMessageBox::Ok == QMessageBox::warning(nullptr, QObject::tr(title.c_str()),
diff --git a/src/yuzu/multiplayer/state.cpp b/src/yuzu/multiplayer/state.cpp
index 66e098296..285bb150d 100644
--- a/src/yuzu/multiplayer/state.cpp
+++ b/src/yuzu/multiplayer/state.cpp
@@ -44,9 +44,6 @@ MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_lis
status_text = new ClickableLabel(this);
status_icon = new ClickableLabel(this);
- status_text->setToolTip(tr("Current connection status"));
- status_text->setText(tr("Not Connected. Click here to find a room!"));
- status_icon->setPixmap(QIcon::fromTheme(QStringLiteral("disconnected")).pixmap(16));
connect(status_text, &ClickableLabel::clicked, this, &MultiplayerState::OnOpenNetworkRoom);
connect(status_icon, &ClickableLabel::clicked, this, &MultiplayerState::OnOpenNetworkRoom);
@@ -57,6 +54,8 @@ MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_lis
HideNotification();
}
});
+
+ retranslateUi();
}
MultiplayerState::~MultiplayerState() = default;
@@ -90,14 +89,7 @@ void MultiplayerState::Close() {
void MultiplayerState::retranslateUi() {
status_text->setToolTip(tr("Current connection status"));
- if (current_state == Network::RoomMember::State::Uninitialized) {
- status_text->setText(tr("Not Connected. Click here to find a room!"));
- } else if (current_state == Network::RoomMember::State::Joined ||
- current_state == Network::RoomMember::State::Moderator) {
- status_text->setText(tr("Connected"));
- } else {
- status_text->setText(tr("Not Connected"));
- }
+ UpdateNotificationStatus();
if (lobby) {
lobby->RetranslateUi();
@@ -113,21 +105,55 @@ void MultiplayerState::retranslateUi() {
}
}
+void MultiplayerState::SetNotificationStatus(NotificationStatus status) {
+ notification_status = status;
+ UpdateNotificationStatus();
+}
+
+void MultiplayerState::UpdateNotificationStatus() {
+ switch (notification_status) {
+ case NotificationStatus::Unitialized:
+ status_icon->setPixmap(QIcon::fromTheme(QStringLiteral("disconnected")).pixmap(16));
+ status_text->setText(tr("Not Connected. Click here to find a room!"));
+ leave_room->setEnabled(false);
+ show_room->setEnabled(false);
+ break;
+ case NotificationStatus::Disconnected:
+ status_icon->setPixmap(QIcon::fromTheme(QStringLiteral("disconnected")).pixmap(16));
+ status_text->setText(tr("Not Connected"));
+ leave_room->setEnabled(false);
+ show_room->setEnabled(false);
+ break;
+ case NotificationStatus::Connected:
+ status_icon->setPixmap(QIcon::fromTheme(QStringLiteral("connected")).pixmap(16));
+ status_text->setText(tr("Connected"));
+ leave_room->setEnabled(true);
+ show_room->setEnabled(true);
+ break;
+ case NotificationStatus::Notification:
+ status_icon->setPixmap(
+ QIcon::fromTheme(QStringLiteral("connected_notification")).pixmap(16));
+ status_text->setText(tr("New Messages Received"));
+ leave_room->setEnabled(true);
+ show_room->setEnabled(true);
+ break;
+ }
+
+ // Clean up status bar if game is running
+ if (system.IsPoweredOn()) {
+ status_text->clear();
+ }
+}
+
void MultiplayerState::OnNetworkStateChanged(const Network::RoomMember::State& state) {
LOG_DEBUG(Frontend, "Network State: {}", Network::GetStateStr(state));
if (state == Network::RoomMember::State::Joined ||
state == Network::RoomMember::State::Moderator) {
OnOpenNetworkRoom();
- status_icon->setPixmap(QIcon::fromTheme(QStringLiteral("connected")).pixmap(16));
- status_text->setText(tr("Connected"));
- leave_room->setEnabled(true);
- show_room->setEnabled(true);
+ SetNotificationStatus(NotificationStatus::Connected);
} else {
- status_icon->setPixmap(QIcon::fromTheme(QStringLiteral("disconnected")).pixmap(16));
- status_text->setText(tr("Not Connected"));
- leave_room->setEnabled(false);
- show_room->setEnabled(false);
+ SetNotificationStatus(NotificationStatus::Disconnected);
}
current_state = state;
@@ -185,6 +211,10 @@ void MultiplayerState::OnAnnounceFailed(const WebService::WebResult& result) {
QMessageBox::Ok);
}
+void MultiplayerState::OnSaveConfig() {
+ emit SaveConfig();
+}
+
void MultiplayerState::UpdateThemedIcons() {
if (show_notification) {
status_icon->setPixmap(
@@ -209,13 +239,16 @@ static void BringWidgetToFront(QWidget* widget) {
void MultiplayerState::OnViewLobby() {
if (lobby == nullptr) {
lobby = new Lobby(this, game_list_model, announce_multiplayer_session, system);
+ connect(lobby, &Lobby::SaveConfig, this, &MultiplayerState::OnSaveConfig);
}
+ lobby->RefreshLobby();
BringWidgetToFront(lobby);
}
void MultiplayerState::OnCreateRoom() {
if (host_room == nullptr) {
host_room = new HostRoomWindow(this, game_list_model, announce_multiplayer_session, system);
+ connect(host_room, &HostRoomWindow::SaveConfig, this, &MultiplayerState::OnSaveConfig);
}
BringWidgetToFront(host_room);
}
@@ -235,7 +268,7 @@ bool MultiplayerState::OnCloseRoom() {
return true;
}
// Save ban list
- UISettings::values.multiplayer_ban_list = std::move(room->GetBanList());
+ UISettings::values.multiplayer_ban_list = room->GetBanList();
room->Destroy();
announce_multiplayer_session->Stop();
@@ -249,14 +282,13 @@ void MultiplayerState::ShowNotification() {
return; // Do not show notification if the chat window currently has focus
show_notification = true;
QApplication::alert(nullptr);
- status_icon->setPixmap(QIcon::fromTheme(QStringLiteral("connected_notification")).pixmap(16));
- status_text->setText(tr("New Messages Received"));
+ QApplication::beep();
+ SetNotificationStatus(NotificationStatus::Notification);
}
void MultiplayerState::HideNotification() {
show_notification = false;
- status_icon->setPixmap(QIcon::fromTheme(QStringLiteral("connected")).pixmap(16));
- status_text->setText(tr("Connected"));
+ SetNotificationStatus(NotificationStatus::Connected);
}
void MultiplayerState::OnOpenNetworkRoom() {
@@ -279,6 +311,8 @@ void MultiplayerState::OnOpenNetworkRoom() {
void MultiplayerState::OnDirectConnectToRoom() {
if (direct_connect == nullptr) {
direct_connect = new DirectConnectWindow(system, this);
+ connect(direct_connect, &DirectConnectWindow::SaveConfig, this,
+ &MultiplayerState::OnSaveConfig);
}
BringWidgetToFront(direct_connect);
}
diff --git a/src/yuzu/multiplayer/state.h b/src/yuzu/multiplayer/state.h
index c92496413..5d681c5c6 100644
--- a/src/yuzu/multiplayer/state.h
+++ b/src/yuzu/multiplayer/state.h
@@ -22,6 +22,13 @@ class MultiplayerState : public QWidget {
Q_OBJECT;
public:
+ enum class NotificationStatus {
+ Unitialized,
+ Disconnected,
+ Connected,
+ Notification,
+ };
+
explicit MultiplayerState(QWidget* parent, QStandardItemModel* game_list, QAction* leave_room,
QAction* show_room, Core::System& system_);
~MultiplayerState();
@@ -31,6 +38,10 @@ public:
*/
void Close();
+ void SetNotificationStatus(NotificationStatus state);
+
+ void UpdateNotificationStatus();
+
ClickableLabel* GetStatusText() const {
return status_text;
}
@@ -64,6 +75,7 @@ public slots:
void OnOpenNetworkRoom();
void OnDirectConnectToRoom();
void OnAnnounceFailed(const WebService::WebResult&);
+ void OnSaveConfig();
void UpdateThemedIcons();
void ShowNotification();
void HideNotification();
@@ -72,6 +84,7 @@ signals:
void NetworkStateChanged(const Network::RoomMember::State&);
void NetworkError(const Network::RoomMember::Error&);
void AnnounceFailed(const WebService::WebResult&);
+ void SaveConfig();
private:
Lobby* lobby = nullptr;
@@ -85,6 +98,7 @@ private:
QAction* show_room;
std::shared_ptr<Core::AnnounceMultiplayerSession> announce_multiplayer_session;
Network::RoomMember::State current_state = Network::RoomMember::State::Uninitialized;
+ NotificationStatus notification_status = NotificationStatus::Unitialized;
bool has_mod_perms = false;
Network::RoomMember::CallbackHandle<Network::RoomMember::State> state_callback_handle;
Network::RoomMember::CallbackHandle<Network::RoomMember::Error> error_callback_handle;
diff --git a/src/yuzu/startup_checks.cpp b/src/yuzu/startup_checks.cpp
index 29b87da05..6a91212e2 100644
--- a/src/yuzu/startup_checks.cpp
+++ b/src/yuzu/startup_checks.cpp
@@ -49,7 +49,7 @@ bool CheckEnvVars(bool* is_child) {
*is_child = true;
return false;
} else if (!SetEnvironmentVariableA(IS_CHILD_ENV_VAR, ENV_VAR_ENABLED_TEXT)) {
- std::fprintf(stderr, "SetEnvironmentVariableA failed to set %s with error %d\n",
+ std::fprintf(stderr, "SetEnvironmentVariableA failed to set %s with error %lu\n",
IS_CHILD_ENV_VAR, GetLastError());
return true;
}
@@ -57,67 +57,72 @@ bool CheckEnvVars(bool* is_child) {
return false;
}
-bool StartupChecks(const char* arg0, bool* has_broken_vulkan) {
+bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulkan_check) {
#ifdef _WIN32
// Set the startup variable for child processes
const bool env_var_set = SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, ENV_VAR_ENABLED_TEXT);
if (!env_var_set) {
- std::fprintf(stderr, "SetEnvironmentVariableA failed to set %s with error %d\n",
+ std::fprintf(stderr, "SetEnvironmentVariableA failed to set %s with error %lu\n",
STARTUP_CHECK_ENV_VAR, GetLastError());
return false;
}
- PROCESS_INFORMATION process_info;
- std::memset(&process_info, '\0', sizeof(process_info));
-
- if (!SpawnChild(arg0, &process_info, 0)) {
- return false;
- }
-
- // Wait until the processs exits and get exit code from it
- WaitForSingleObject(process_info.hProcess, INFINITE);
- DWORD exit_code = STILL_ACTIVE;
- const int err = GetExitCodeProcess(process_info.hProcess, &exit_code);
- if (err == 0) {
- std::fprintf(stderr, "GetExitCodeProcess failed with error %d\n", GetLastError());
- }
-
- // Vulkan is broken if the child crashed (return value is not zero)
- *has_broken_vulkan = (exit_code != 0);
-
- if (CloseHandle(process_info.hProcess) == 0) {
- std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError());
- }
- if (CloseHandle(process_info.hThread) == 0) {
- std::fprintf(stderr, "CloseHandle failed with error %d\n", GetLastError());
+ if (perform_vulkan_check) {
+ // Spawn child process that performs Vulkan check
+ PROCESS_INFORMATION process_info;
+ std::memset(&process_info, '\0', sizeof(process_info));
+
+ if (!SpawnChild(arg0, &process_info, 0)) {
+ return false;
+ }
+
+ // Wait until the processs exits and get exit code from it
+ WaitForSingleObject(process_info.hProcess, INFINITE);
+ DWORD exit_code = STILL_ACTIVE;
+ const int err = GetExitCodeProcess(process_info.hProcess, &exit_code);
+ if (err == 0) {
+ std::fprintf(stderr, "GetExitCodeProcess failed with error %lu\n", GetLastError());
+ }
+
+ // Vulkan is broken if the child crashed (return value is not zero)
+ *has_broken_vulkan = (exit_code != 0);
+
+ if (CloseHandle(process_info.hProcess) == 0) {
+ std::fprintf(stderr, "CloseHandle failed with error %lu\n", GetLastError());
+ }
+ if (CloseHandle(process_info.hThread) == 0) {
+ std::fprintf(stderr, "CloseHandle failed with error %lu\n", GetLastError());
+ }
}
if (!SetEnvironmentVariableA(STARTUP_CHECK_ENV_VAR, nullptr)) {
- std::fprintf(stderr, "SetEnvironmentVariableA failed to clear %s with error %d\n",
+ std::fprintf(stderr, "SetEnvironmentVariableA failed to clear %s with error %lu\n",
STARTUP_CHECK_ENV_VAR, GetLastError());
}
#elif defined(YUZU_UNIX)
- const pid_t pid = fork();
- if (pid == 0) {
- CheckVulkan();
- return true;
- } else if (pid == -1) {
- const int err = errno;
- std::fprintf(stderr, "fork failed with error %d\n", err);
- return false;
- }
-
- // Get exit code from child process
- int status;
- const int r_val = wait(&status);
- if (r_val == -1) {
- const int err = errno;
- std::fprintf(stderr, "wait failed with error %d\n", err);
- return false;
+ if (perform_vulkan_check) {
+ const pid_t pid = fork();
+ if (pid == 0) {
+ CheckVulkan();
+ return true;
+ } else if (pid == -1) {
+ const int err = errno;
+ std::fprintf(stderr, "fork failed with error %d\n", err);
+ return false;
+ }
+
+ // Get exit code from child process
+ int status;
+ const int r_val = wait(&status);
+ if (r_val == -1) {
+ const int err = errno;
+ std::fprintf(stderr, "wait failed with error %d\n", err);
+ return false;
+ }
+ // Vulkan is broken if the child crashed (return value is not zero)
+ *has_broken_vulkan = (status != 0);
}
- // Vulkan is broken if the child crashed (return value is not zero)
- *has_broken_vulkan = (status != 0);
#endif
return false;
}
@@ -130,7 +135,8 @@ bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags) {
startup_info.cb = sizeof(startup_info);
char p_name[255];
- std::strncpy(p_name, arg0, 255);
+ std::strncpy(p_name, arg0, 254);
+ p_name[254] = '\0';
const bool process_created = CreateProcessA(nullptr, // lpApplicationName
p_name, // lpCommandLine
@@ -144,7 +150,7 @@ bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags) {
pi // lpProcessInformation
);
if (!process_created) {
- std::fprintf(stderr, "CreateProcessA failed with error %d\n", GetLastError());
+ std::fprintf(stderr, "CreateProcessA failed with error %lu\n", GetLastError());
return false;
}
diff --git a/src/yuzu/startup_checks.h b/src/yuzu/startup_checks.h
index f2fc2d9d4..d8e563be6 100644
--- a/src/yuzu/startup_checks.h
+++ b/src/yuzu/startup_checks.h
@@ -13,7 +13,7 @@ constexpr char ENV_VAR_ENABLED_TEXT[] = "ON";
void CheckVulkan();
bool CheckEnvVars(bool* is_child);
-bool StartupChecks(const char* arg0, bool* has_broken_vulkan);
+bool StartupChecks(const char* arg0, bool* has_broken_vulkan, bool perform_vulkan_check);
#ifdef _WIN32
bool SpawnChild(const char* arg0, PROCESS_INFORMATION* pi, int flags);
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h
index e12d414d9..4f5b2a99d 100644
--- a/src/yuzu/uisettings.h
+++ b/src/yuzu/uisettings.h
@@ -102,7 +102,7 @@ struct Values {
Settings::Setting<uint32_t> callout_flags{0, "calloutFlags"};
// multiplayer settings
- Settings::Setting<QString> multiplayer_nickname{QStringLiteral("yuzu"), "nickname"};
+ Settings::Setting<QString> multiplayer_nickname{{}, "nickname"};
Settings::Setting<QString> multiplayer_ip{{}, "ip"};
Settings::SwitchableSetting<uint, true> multiplayer_port{24872, 0, UINT16_MAX, "port"};
Settings::Setting<QString> multiplayer_room_nickname{{}, "room_nickname"};
@@ -129,6 +129,9 @@ struct Values {
Settings::Setting<bool> favorites_expanded{true, "favorites_expanded"};
QVector<u64> favorited_ids;
+ // Compatibility List
+ Settings::Setting<bool> show_compat{false, "show_compat"};
+
bool configuration_applied;
bool reset_to_defaults;
Settings::Setting<bool> disable_web_applet{true, "disable_web_applet"};
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index 3a0f33cba..e16f79eb4 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -302,6 +302,8 @@ int main(int argc, char** argv) {
}
Core::System system{};
+ system.Initialize();
+
InputCommon::InputSubsystem input_subsystem{};
// Apply the command line arguments
@@ -392,7 +394,7 @@ int main(int argc, char** argv) {
}
system.DetachDebugger();
void(system.Pause());
- system.Shutdown();
+ system.ShutdownMainProcess();
detached_tasks.WaitForAllTasks();
return 0;